I was reading through an example of how to use metaprogramming to make attribute accessors, and I'm a bit confused on where this value variable came from:
class AttrAccessorObject
def self.my_attr_accessor(*names)
names.each do | name |
define_method(name) {
self.instance_variable_get("@#{name}".to_sym)
}
define_method("#{name}=") do | value |
self.instance_variable_set("@#{name}".to_sym, value)
end
end
end
end
I understand that the instance_variable_set method needs both the instance variable and the value to set the instance variable's new value, but where did this value variable in the code come from? Also, since it's using a "do/end" loop to use the value, I'm assuming that the "define_method("#{name}=") evaluates to an array of values, is that correct?
If you think of what a 'normal' method definition looks like:
The
|value|part is the same as(value)- it declares the arguments that are accepted by the method you're defining. So if I wanted to make a method that takes 3 args:No, blocks are not just used with arrays. Think of a block like an anonymous function that is used as a parameter for another function. The function you call (e.g.
each) may internally invoke the anonymous function 0, 1, or any number of times. In the case ofeach, it calls it N times (one time for each array element):but in the case of
tap, it calls it only once: