Eye Matz wrote:
class Important
def set_this_value_method(value)
end
end
class SemiImportant < Important
set_this_value_method :something_or_anything
end
Could some kind sould please, please take the time to explain the
fundamentals of Ruby's class/module functionality in regards to the
above example.
Since you asked for a fundimental level explaination I hope this helps
and doesn't seem pretentious:
A class is an object, and like all objects it can have different
attributes or "properties" which control how it behaves. In your
example the def keyword is used to give the Important class object a
special attribute called a method. That is basically just a block of
code that has a name and when that name is dereferenced the code is
executed and whatever arguments you pass the method become available
inside the code block (as well as any other methods or variables in the
context where you call the method from). So visually you can picture it
like this:
Important +
>
set_this_value_method ---> [code block]
But set_this_value_method can't be called directly from Important
(i.e., Important.set_this_value_method) because it wants an instance as
its caller rather than the actual class object. To make an instance you
use Important.new. So Important.new.set_this_value_method finds the
code block of set_this_value_method in the instance object of class
Important, and executes it. To just use the method with the class
object as the caller rather than an instance, you can use def
self.set_this_value_method.
In the second case, you're "subclassing" the Important class object:
class SemiImportant < Important. That is like taking all of the
attributes from Important and adding them to SemiImportant, as if you
had typed them in that class by hand.
Important ----+
SemiImportant +
>
set_this_value_method ---> [code block]
And since you then have "set_this_value_method :something_or_anything"
directly in the class body (i.e., outside of a method definition), as
soon as the interpreter parses the class definition it will run that
code. But since you are in the class object itself and not an instance,
you can't see set_this_value_method in the superclass (Important). But
if you use the class method (def self.set_this_value_method) in class
Important, then it will work correctly. Another option would be to
place this into a special method definition named initialize, which
will only be called when you create an instance of SemiImportant. And
in that case you must call the #super method to initialize the
superclass as well since you are overriding its constructor (the
initialize method).
So, either:
class Important
def self.set_this_value_method(value)
p value
end
end
class SemiImportant < Important
set_this_value_method 'foo' # called now
end
Or:
class Important
def set_this_value_method(value)
p value
end
end
class SemiImportant < Important
def initialize
super # initialize the superclass also
set_this_value_method 'foo'
end
end
SemiImportant.new # called now
I hope this wasn't too basic. I just didn't want to assume anything and
confuse you further (though I'm sure I probably did anyhow, what with
my babling)! But it's better too have much info you already know than
not enough that you dodn't. 
Regards,
Jordan