[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Newbie: Question => How to do this with Classes ?

Eye Matz

10/3/2006 12:34:00 PM

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.

I'm a photographer/php 'programmer' so I speak fairly good English, but
very little geek speak, so please don't assume too much. Having said
the above, I've created fairly complex class structures/frameworks in
PHP, so I'm not completely dense, although grepping Ruby's syntax
certainly makes me feel that way.

I have the books "Pickaxe", "Ruby for Rails" & "AWDR" and I have tried
to read my way to an answer, but these books are designed for
programmers, and not visual people like myself, so hence I can't see the
answers in them, even though they may well be in there.

To give you the context of my question, please consider this Rails code
example:

class DumbNewbie < ActiveRecord::Base
has_many :questions
end

Hope I've been clear, yet succinct, enough to not waste too much
bandwith. I'll be extremely grateful for anyone taking the time to get
me over this major hurdle.

--
Posted via http://www.ruby-....

14 Answers

Jean Helou

10/3/2006 12:43:00 PM

0

See this post: http://ola-bini.blogspot.com/2006/09/ruby-metaprogramming-techn...

I think the second point is what you seek, and it is explained too :)

good luck
jean

On 10/3/06, Eye Matz <matz@eyematz.com> 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.
>
> I'm a photographer/php 'programmer' so I speak fairly good English, but
> very little geek speak, so please don't assume too much. Having said
> the above, I've created fairly complex class structures/frameworks in
> PHP, so I'm not completely dense, although grepping Ruby's syntax
> certainly makes me feel that way.
>
> I have the books "Pickaxe", "Ruby for Rails" & "AWDR" and I have tried
> to read my way to an answer, but these books are designed for
> programmers, and not visual people like myself, so hence I can't see the
> answers in them, even though they may well be in there.
>
> To give you the context of my question, please consider this Rails code
> example:
>
> class DumbNewbie < ActiveRecord::Base
> has_many :questions
> end
>
> Hope I've been clear, yet succinct, enough to not waste too much
> bandwith. I'll be extremely grateful for anyone taking the time to get
> me over this major hurdle.
>
> --
> Posted via http://www.ruby-....
>
>

Eye Matz

10/3/2006 1:05:00 PM

0

Jean Helou wrote:
> See this post:
> http://ola-bini.blogspot.com/2006/09/ruby-metaprogramming-techn...
>
> I think the second point is what you seek, and it is explained too :)

Hi Jean,

Thanks for your reply, but I'm sorry to say, that page contains just
more confusion. A copy&paste job and changing of that code into my test
scenario just causes an error
"NameError: undefined local variable or method â??singleton_classâ?? for..."

The blog post is hitting me way too high, and so does 95% of all other
examples I've found so far.

But please take that bit of code and rewrite it, WITH clear and
extensive comments for each line of code, within my given example in the
original post, and maybe then I can test run it and work it out from
there. I learn from code that is gradually (slowly!!) extended into
doing what I want it to do,

WIthout that it's just geek speak, and no way near fluent in that :(

--
Posted via http://www.ruby-....

dblack

10/3/2006 1:07:00 PM

0

Tim Hunter

10/3/2006 1:30:00 PM

0

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.
>
> I'm a photographer/php 'programmer' so I speak fairly good English, but
> very little geek speak, so please don't assume too much. Having said
> the above, I've created fairly complex class structures/frameworks in
> PHP, so I'm not completely dense, although grepping Ruby's syntax
> certainly makes me feel that way.
>
> I have the books "Pickaxe", "Ruby for Rails" & "AWDR" and I have tried
> to read my way to an answer, but these books are designed for
> programmers, and not visual people like myself, so hence I can't see the
> answers in them, even though they may well be in there.
>

Let me recommend Why's (Poignant) Guide to Ruby:
http://www.poignantguide... as a good introduction to Ruby that's
more accessible to "visual people."

Since you've already got some programming experience you may be able to
just skim the first parts. Or, more likely, just read them for their
entertainment value :-)

Good luck!

Jean Helou

10/3/2006 1:31:00 PM

0

My explanation or any other good explanations won't make sense if you
don't understand the singleton_class concept. There is a diagram which
explains it in the pickaxe book, if I remember correctly it's in the
duck typing section.

The singleton_class is like an instance-specific proxy for the class.
when you add a method to the singleton_class it is like modifying the
class of the instance but only for this particular instance.

now for your example :
class Important
def singleton_class
#get the singleton class for this instance
#A good explanation for the singleton class is available in the pickaxe book
#if i remember correctly it's in the duck typing section with a diagram
#which makes it all clear.
class << self; self; end
end

#define the class method which will be available as a dsl element.
#this is only "syntactic sugar" for your dsl to make it nicer
def self.set_this_value_method(value)
define_attr_method :this_value_method, value
end

#Then defines a new method called "name" in the singleton class of
the instance.
#note that here the instance is a class thus it adds a class method
def self.define_attr_method(name, value)
singleton_class.class_eval do
define_method(name) do
value
end
end

end


class SemiImportant < Important
set_this_value_method :something_or_anything
end

now you can call SemiImportant.this_value_method and it will return
:something_or_anything

jean

On 10/3/06, Eye Matz <matz@eyematz.com> wrote:
> Jean Helou wrote:
> > See this post:
> > http://ola-bini.blogspot.com/2006/09/ruby-metaprogramming-techn...
> >
> > I think the second point is what you seek, and it is explained too :)
>
> Hi Jean,
>
> Thanks for your reply, but I'm sorry to say, that page contains just
> more confusion. A copy&paste job and changing of that code into my test
> scenario just causes an error
> "NameError: undefined local variable or method 'singleton_class' for..."
>
> The blog post is hitting me way too high, and so does 95% of all other
> examples I've found so far.
>
> But please take that bit of code and rewrite it, WITH clear and
> extensive comments for each line of code, within my given example in the
> original post, and maybe then I can test run it and work it out from
> there. I learn from code that is gradually (slowly!!) extended into
> doing what I want it to do,
>
> WIthout that it's just geek speak, and no way near fluent in that :(
>
> --
> Posted via http://www.ruby-....
>
>

Jean Helou

10/3/2006 2:19:00 PM

0

On 10/3/06, Tim Hunter <sastph@sas.com> wrote:
> 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.
> >
> > I'm a photographer/php 'programmer' so I speak fairly good English, but
> > very little geek speak, so please don't assume too much. Having said
> > the above, I've created fairly complex class structures/frameworks in
> > PHP, so I'm not completely dense, although grepping Ruby's syntax
> > certainly makes me feel that way.
> >
> > I have the books "Pickaxe", "Ruby for Rails" & "AWDR" and I have tried
> > to read my way to an answer, but these books are designed for
> > programmers, and not visual people like myself, so hence I can't see the
> > answers in them, even though they may well be in there.
> >
>
> Let me recommend Why's (Poignant) Guide to Ruby:
> http://www.poignantguide... as a good introduction to Ruby that's
> more accessible to "visual people."
>
> Since you've already got some programming experience you may be able to
> just skim the first parts. Or, more likely, just read them for their
> entertainment value :-)
>
> Good luck!
>
>
see also http://whytheluckystiff.net/articles/seeingMetaclassesCl...
for an explanation on singleton_classes (aka metaclasses)

jean

MonkeeSage

10/3/2006 2:27:00 PM

0

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

Eye Matz

10/3/2006 2:50:00 PM

0

unknown wrote:
> So, you could do this:
>
> class Important
> def self.set_this_value_method(value) # note the 'self'
> end
> end
>
> class SemiImportant < Important
> set_this_value_method :x
> end

Hi David,

Thanks for your reply! This was very much the way I was trying to do
things and expecting things to work, but when I did it, things did NOT
work. Go figure! :( Having taken yours & Jean's replies, I came up with
this heavily commented code, WITH lots of questions inside the comments
:)

==============

# base class that is extended by other classes for shared
methods/variables within the
# instance object
class Important
# Not sure if this is really needed, or how to refer/change this to a
@@class_variable ??
attr_accessor :my_value

# the method that will be used in sub-classes to set the internal
value
def self.set_this_value_method(value) # note the 'self'
# commented out use of class variable, since using a method is
better for
# possible expansion in the future
#@@my_value = value
# call to internal method that sets the value to the class variable
self.set_my_value(value)
end

# method that sets/(process) the actuall value
def self.set_my_value(value)
# using class variable here, but don't understand fully WHY?
# should ideally be normal instance variable, but don't know how
@@my_value = value
# why does not this type of syntax work ?
#self.my_value = value
end

# just dumps the value out
def get_my_value
@@my_value
end

def the_value
# using the method instead of the variable here
"the_value: my value is [#{get_my_value}]"
end
end

# sub-class that is based upon base class
class SemiImportant < Important
# here we set the internal 'my_value' variable to something
set_this_value_method 'something'
end

# creating a new instance
sc = SemiImportant.new
# why does this NOT show the my_value variable?
# how could I make it show this variable?
puts sc.inspect # => #<SemiImportant:0x35409c>

puts sc.get_my_value # => something
puts sc.the_value # => the_value: my value is [something]
puts sc.my_value # => nil
# with this call I can change the value of my_value
sc.class.superclass.set_my_value("Don't understand fully")
# but I cannot retrieve the value set with this call. WHY??
puts sc.class.superclass.my_value

==========

Hopefully someone else that is struggling with the same can find this
little snippet and hopefully save themselves some over-worked brain
cells.

If you (anyone) can answer the included questions I'd love to know the
answers.

Thanks again.

--
Posted via http://www.ruby-....

Eye Matz

10/3/2006 2:52:00 PM

0

Jean Helou wrote:
> now for your example :
> class Important
> def singleton_class
> #get the singleton class for this instance
> #A good explanation for the singleton class is available in the
> pickaxe book
> #if i remember correctly it's in the duck typing section with a
> diagram
> #which makes it all clear.
> class << self; self; end
> end
>
> #define the class method which will be available as a dsl element.
> #this is only "syntactic sugar" for your dsl to make it nicer
> def self.set_this_value_method(value)
> define_attr_method :this_value_method, value
> end
>
> #Then defines a new method called "name" in the singleton class of
> the instance.
> #note that here the instance is a class thus it adds a class method
> def self.define_attr_method(name, value)
> singleton_class.class_eval do
> define_method(name) do
> value
> end
> end
>
> end
>
>
> class SemiImportant < Important
> set_this_value_method :something_or_anything
> end
>
> now you can call SemiImportant.this_value_method and it will return
> :something_or_anything
>
> jean

Hi Jean,

Thanks you VERY much for making that example clearer !

One minor error in it, though
> def singleton_class
> class << self; self; end
> end

should be

def self.singleton_class
class << self; self; end
end

And Yes, I do understand the concept of Singleton classes, just NOT very
well in Ruby or in Ruby syntax. My problem is really more to do with the
grammatical logic, ie: when should I use this or that, or how should I
write this or that to get this or that result.

I haven't found a clear and concise account of that, and therefore I am
writing stuff like this [ Name are Matz I ] in Ruby, and things don't
work so well then.

Thank you for your help!


--
Posted via http://www.ruby-....

Jean Helou

10/3/2006 2:57:00 PM

0

On 10/3/06, Eye Matz <matz@eyematz.com> wrote:
> Jean Helou wrote:
> > now for your example :
> > class Important
> > def singleton_class
> > #get the singleton class for this instance
> > #A good explanation for the singleton class is available in the
> > pickaxe book
> > #if i remember correctly it's in the duck typing section with a
> > diagram
> > #which makes it all clear.
> > class << self; self; end
> > end
> >
> > #define the class method which will be available as a dsl element.
> > #this is only "syntactic sugar" for your dsl to make it nicer
> > def self.set_this_value_method(value)
> > define_attr_method :this_value_method, value
> > end
> >
> > #Then defines a new method called "name" in the singleton class of
> > the instance.
> > #note that here the instance is a class thus it adds a class method
> > def self.define_attr_method(name, value)
> > singleton_class.class_eval do
> > define_method(name) do
> > value
> > end
> > end
> >
> > end
> >
> >
> > class SemiImportant < Important
> > set_this_value_method :something_or_anything
> > end
> >
> > now you can call SemiImportant.this_value_method and it will return
> > :something_or_anything
> >
> > jean
>
> Hi Jean,
>
> Thanks you VERY much for making that example clearer !
>
> One minor error in it, though
> > def singleton_class
> > class << self; self; end
> > end
>
> should be
>
> def self.singleton_class
> class << self; self; end
> end
>
> And Yes, I do understand the concept of Singleton classes, just NOT very
> well in Ruby or in Ruby syntax. My problem is really more to do with the
> grammatical logic, ie: when should I use this or that, or how should I
> write this or that to get this or that result.
>
> I haven't found a clear and concise account of that, and therefore I am
> writing stuff like this [ Name are Matz I ] in Ruby, and things don't
> work so well then.
>
> Thank you for your help!
>
>
> --
> Posted via http://www.ruby-....
>
>
Maybe this will help since he asked himself the exact same question :
http://wanderingbarque.com/ruby/Dynami...

he understood the how but not the why... hope this helps.

jean