22

私は SaaS スタンフォード クラスを行っており、この課題のパート 5 を実行しようとしています。

私はこの概念を理解するのに本当に苦労しています。これは私がやろうとしたことです:

class Class
  def attr_accessor_with_history(attr_name)
    attr_name = attr_name.to_s
    attr_reader attr_name
    attr_reader attr_name + '_history'
    class_eval %Q'{def #{attr_name}(a);#{attr_name}_history.push(a) ; end;}'
  end
end

私はおそらくあらゆる種類の間違ったことをしています.The Book Of Rubyのメタプログラミングに関する章を読んでも、まだ理解できません.誰かがこれを理解するのを手伝ってくれますか?

4

3 に答える 3

41

これは楽しかったです!!!

class Class
    def attr_accessor_with_history(attr_name)
        attr_name = attr_name.to_s # make sure it's a string
        attr_reader attr_name
        attr_reader attr_name+"_history"
        class_eval %Q"
            def #{attr_name}=(value)
                if !defined? @#{attr_name}_history
                    @#{attr_name}_history = [@#{attr_name}]
                end
                @#{attr_name} = value
                @#{attr_name}_history << value
            end
        "
    end
end

class Foo
    attr_accessor_with_history :bar
end

class Foo2
    attr_accessor_with_history :bar
    def initialize()
        @bar = 'init'
    end
end

f = Foo.new
f.bar = 1
f.bar = nil
f.bar = '2'
f.bar = [1,nil,'2',:three]
f.bar = :three
puts "First bar:", f.bar.inspect, f.bar_history.inspect
puts "Correct?", f.bar_history == [f.class.new.bar, 1, nil, '2', [1,nil,'2',:three], :three] ? "yes" : "no"
old_bar_history = f.bar_history.inspect

f2 = Foo2.new
f2.bar = 'baz'
f2.bar = f2
puts "\nSecond bar:", f2.bar.inspect, f2.bar_history.inspect
puts "Correct?", f2.bar_history == [f2.class.new.bar, 'baz', f2] ? "yes" : "no"

puts "\nIs the old f.bar intact?", f.bar_history.inspect == old_bar_history ? "yes" : "no"

class_eval で文字列を使用する必要がある唯一の理由は、カスタム セッターを定義するときに のを参照できるようにするためであることに注意してください。attr_nameそれ以外の場合は、通常、ブロックを に渡しclass_evalます。

于 2012-03-05T03:51:26.113 に答える
6

あなたがやったことに関して、あなたは実際に解決策の先端にいます。それ #{attr_name}_historyはあなたのコードに存在しないだけです。インスタンス変数を作成し、存在しない場合は nil に設定する必要があります。配列が存在する場合は、配列へのプッシュを処理する必要があります。

それにはいくつかの方法があります。一つの方法は if defined? @#{attr_name}_history DoStuffHere

于 2012-03-05T03:57:06.113 に答える