0

I'm trying to dynamically create methods depending on provided name like page-object gem do. But In my case c.custom = just returning passed argument, like simple assignment.

In my original task I need to send method call with provided value like: self.send(method).send_keys(value)

Also, I notice, when added puts to line "called #{name} with #{value}" and called custom from outside of object like C.new.custom = 123 it will produce expected output, but still that's not what I want.

Is there any way to define required method, to call it inside and outside of object?

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')
brbrr
  • 149
  • 1
  • 1
  • 16
  • @cremno, thanks for link, but it's not my problem. As @engineersmnky notice - I'm assigning to local variable there. I should use `self.custom = 'value'` to make it work. – brbrr Mar 17 '16 at 16:46

1 Answers1

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

I only had to change one line in your code.

There were two problems with your code:

  1. custom = val is not a method call, it assigns to a local variable named custom. If you want to call a setter, you need to make it explicit that you are calling a method, by providing an explicit receiver: self.custom = val. See Why do Ruby setters need “self.” qualification within the class?
  2. Assignments evaluate to the right-hand side of the assignment. The return value of a setter method is ignored, unless you don't use assignment syntax, i.e. public_send. See Why does irb echo the right hand side of an assignment instead of the return value in the case of a setter method?
Community
  • 1
  • 1
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653