define_method for setter 不会在 class 调用中工作

define_method for setter wont work inside class call

我正在尝试根据提供的名称动态创建方法,例如 page-object gem do。但在我的例子中 c.custom = 只是返回传递的参数,就像简单的赋值一样。

在我的原始任务中,我需要发送具有提供值的方法调用,例如: self.send(method).send_keys(value)

此外,我注意到,当将 puts 添加到行 "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')
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. 作业计算到作业的右侧。 setter 方法的 return 值将被忽略,除非您不使用赋值语法,即 public_send。参见