I am trying to create a Ruby class where the initialize
method takes a hash of options. I then have those options as attr_accessor
s for the class. Now, I could do something like
class User
attr_accessor :name, :email, :phone
def initialize(options)
self.name = options[:name]
self.email = options[:email]
self.phone = options[:phone]
end
end
User.new(:name => 'Some Name', :email => '[email protected]', :phone => 435543093)
but it doesn't feel very DRY to me. Instead, I would like to do
class User
attr_accessor :name, :email, :phone
def initialize(options)
options.each do |option_name, option_value|
# Does not work!!
self.send(option_name, '=', option_value)
# Does not work either!!
self.send(option_name, '=' + option_value)
end
end
end
User.new(:name => 'Some Name', :email => '[email protected]', :phone => 435543093)
but I cannot get the syntax to work!
What am I doing wrong?
send sends a message to an object instance and its ancestors in class hierarchy until some method reacts (because its name matches the first argument). Note that send bypasses visibility checks, so that you can call private methods, too (useful for unit testing).
Ruby Language Metaprogramming send() method send() is used to pass message to object . send() is an instance method of the Object class. The first argument in send() is the message that you're sending to the object - that is, the name of a method. It could be string or symbol but symbols are preferred.
self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everwhere: For instance variables: @myvar. For method and constant lookup. When defining methods, classes and modules.
You're getting this problem because the method name is wrong. When using a send with a setter, you'll need to include the =
in the method name, like this:
self.send("#{option_name}=", option_value)
The above should do the trick.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With