On Sun, Apr 24, 2011 at 9:29 AM, Jeroen v. [email protected]
In this way I can succesfully set the price per liter of the class. How
can I make it dunamically, so I can also set the attribute ‘price’?
I tried instance_variable_set(@variable, val), but that doesn’t work.
Probably because the variables of the class ‘foo’ and the module ‘bar’
lives independent of each other.
What was the error it gave you? From here, I have a hard time believing
tried setting the ivar, because your code has two syntax errors (classes
modules must be constants) a name error (price is neither a local
nor a method), and you can not set the price per liter of the class as
say you did, since price_per_liter is a local variable and there is no
price_per_liter= method, anyway.
Anyway, everything in Ruby is an object, including classes. Every object
Ruby has a singleton class, which is a class just for that one object
are created lazily). Why is this relevant? Because methods are defined
classes, so defining methods on the object’s singleton class will define
methods for that one object. This is what class methods are.
So what about modules? When you extend an object (and classes are
with a module, it gets put in the ancestry chain behind the singleton
So when you ask the object for its methods, it looks in the singleton
and when it doesn’t find it, it goes up the chain into the module, where
discovers the method.
So, we just define the #price= method in the module, then we extend the
class with the module, and now the class has access to that method.
define the price method on the
singleton class of Foo
define the price= method as an
instance method of Bar
@price = new_price
put Bar as an ancestor of
Foo’s singleton class
tada, everything works
Foo.price # => nil
Foo.price = 5
Foo.price # => 5
You also look like you don’t understand the difference between local
variables, instance variables, and methods. In Ruby, all instance
are private, and they always begin with the @ sigil. So @price is an
instance variable, and price is either a local variable or a method.
price_per_liter = 1 in your code above, you are setting a
variable. If you want to invoke a method on self, you need
self.price_per_liter = 1 to disambiguate. If you want to set the
variable, you need
@price_per_liter = 1
Note that Ruby has syntactic sugar to turn
self.price = 1 into
self.price=(1), that assignment is just a method call.