pegacornの日記 このページをアンテナに追加 RSSフィード

2007-04-12 [Ruby][clone]

[][]深いコピーの作成(2)

深いコピーの作成(1)

組み込みクラス Array, Hash 用のメソッドを作ってみた。

clone.rb
#!ruby

class Object
  def deep_clone
    return @deep_cloning_obj if @deep_cloning
    @deep_cloning_obj = clone
    @deep_cloning_obj.instance_variables.each do |var|
      val = @deep_cloning_obj.instance_variable_get(var)
      begin
        @deep_cloning = true
        val = val.deep_clone
      rescue TypeError
        next
      ensure
        @deep_cloning = false
      end
      @deep_cloning_obj.instance_variable_set(var, val)
    end
    deep_cloning_obj = @deep_cloning_obj
    @deep_cloning_obj = nil
    deep_cloning_obj
  end
end

class Array
  def deep_clone
    return @deep_cloning_obj if @deep_cloning
    @deep_cloning_obj = super
    @deep_cloning_obj.map! do |val|
      begin
        @deep_cloning = true
        val = val.deep_clone
      rescue TypeError
        #
      ensure
        @deep_cloning = false
      end
      val
    end
    deep_cloning_obj = @deep_cloning_obj
    @deep_cloning_obj = nil
    deep_cloning_obj
  end
end

class Hash
  def deep_clone
    return @deep_cloning_obj if @deep_cloning
    @deep_cloning_obj = super
    pairs = @deep_cloning_obj.to_a
    @deep_cloning_obj.clear
    pairs.each do |pair|
      pair.map! do |val|
        begin
          @deep_cloning = true
          val = val.deep_clone
        rescue TypeError
          #
        ensure
          @deep_cloning = false
        end
        val
      end
      @deep_cloning_obj[pair[0]] = pair[1]
    end
    deep_cloning_obj = @deep_cloning_obj
    @deep_cloning_obj = nil
    deep_cloning_obj
  end
end
実行例1
require 'clone'

class Foo
end

class Bar
end

obj = [Foo.new, Bar.new]
p obj                   # => [#<Foo:0x100ed494>, #<Bar:0x100ed480>]
p obj.clone             # => [#<Foo:0x100ed494>, #<Bar:0x100ed480>]
p obj.deep_clone        # => [#<Foo:0x100ed340>, #<Bar:0x100ed318>]
実行例2
require 'clone'

class Foo
end

class Bar
end

obj = {Foo.new => Bar.new, Foo.new => Bar.new}
p obj                   # => {#<Foo:0x100ed3a4>=>#<Bar:0x100ed390>, #<Foo:0x100ed37c>=>#<Bar:0x100ed368>}
p obj.clone             # => {#<Foo:0x100ed3a4>=>#<Bar:0x100ed390>, #<Foo:0x100ed37c>=>#<Bar:0x100ed368>}
p obj.deep_clone        # => {#<Foo:0x100ed188>=>#<Bar:0x100ed160>, #<Foo:0x100ed138>=>#<Bar:0x100ed110>}

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/pegacorn/20070412/1176381225