gpt4 book ai didi

Ruby - 使用 class_eval 定义方法

转载 作者:数据小太阳 更新时间:2023-10-29 06:29:35 25 4
gpt4 key购买 nike

我正在学习 SaaS 斯坦福类(class),尝试完成 this assignment 的第 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

我可能做错了各种各样的事情,阅读了 Ruby 之书关于元编程的章节,但我仍然不明白,有人可以帮助我理解这一点吗?

最佳答案

这很有趣!!!

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 一起使用的唯一原因是您可以在定义自定义 setter 时引用 attr_namevalue。否则通常会将一个 block 传递给 class_eval

关于Ruby - 使用 class_eval 定义方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9561072/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com