setter的define_method不会在类调用中工作

时间:2016-03-17 16:18:24

标签: ruby metaprogramming page-object-gem

我正在尝试根据提供的名称page-object gem do动态创建方法。但在我的情况下"called #{name} with #{value}"只返回传递的参数,就像简单的赋值一样。

在我的原始任务中,我需要使用提供的值发送方法调用,如: custom

另外,我注意到,当C.new.custom = 123添加到行module M def create(name) define_method("#{name}=") do |value| "called #{name} with #{value}" end end end class C extend M create(:custom) def initialize(val) puts custom = val end end C.new('haha') 并从{{1}}之类的对象外部调用{{1}}时,它会产生预期的输出,但仍然不是我想要。

有没有办法定义所需的方法,在对象的内部和外部调用它?

{{1}}

1 个答案:

答案 0 :(得分:1)

module M
  def create(name)
    define_method("#{name}=") do |value|
     "called #{name} with #{value}"
    end
  end
end

class C
  extend M
  create(:custom)
  def initialize(val)
    puts public_send(:custom=, val) # this is the only change needed
  end
end

C.new('haha')
# called custom with haha

我只需要更改代码中的一行。

您的代码存在两个问题:

  1. custom = val不是方法调用,它分配给名为custom的局部变量。如果要调用setter,则需要通过提供明确的接收器来明确表示您正在调用方法:self.custom = val。请参阅Why do Ruby setters need “self.” qualification within the class?
  2. 作业评估到作业的右侧。除非您不使用赋值语法,即public_send,否则将忽略setter方法的返回值。请参阅Why does irb echo the right hand side of an assignment instead of the return value in the case of a setter method?