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

Discussion in 'Ruby' started by Eye Matz, Oct 3, 2006.

  1. Eye Matz

    Eye Matz Guest

    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-forum.com/.
    Eye Matz, Oct 3, 2006
    #1
    1. Advertising

  2. Eye Matz

    Jean Helou Guest

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

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

    good luck
    jean

    On 10/3/06, 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.
    >
    > 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-forum.com/.
    >
    >
    Jean Helou, Oct 3, 2006
    #2
    1. Advertising

  3. Eye Matz

    Eye Matz Guest

    Jean Helou wrote:
    > See this post:
    > http://ola-bini.blogspot.com/2006/09/ruby-metaprogramming-techniques.html
    >
    > 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-forum.com/.
    Eye Matz, Oct 3, 2006
    #3
  4. Eye Matz

    Guest

    Hi --

    On Tue, 3 Oct 2006, 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.


    In the second snippet, you're sending the message
    "set_this_value_method" to the class object SemiImportant. In order
    for that object to understand the message, a method called
    set_this_value_method has to be defined either in

    1. the object's class (which, in this case, is actually Class
    2. on a singleton (per-object) basis for the object
    3. on a singleton basis in the object's super[super[super...]]class.

    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


    David

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
    , Oct 3, 2006
    #4
  5. Eye Matz

    Tim Hunter Guest

    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.net/ruby/ 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!
    Tim Hunter, Oct 3, 2006
    #5
  6. Eye Matz

    Jean Helou Guest

    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 <> wrote:
    > Jean Helou wrote:
    > > See this post:
    > > http://ola-bini.blogspot.com/2006/09/ruby-metaprogramming-techniques.html
    > >
    > > 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-forum.com/.
    >
    >
    Jean Helou, Oct 3, 2006
    #6
  7. Eye Matz

    Jean Helou Guest

    On 10/3/06, Tim Hunter <> 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.net/ruby/ 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/seeingMetaclassesClearly.html
    for an explanation on singleton_classes (aka metaclasses)

    jean
    Jean Helou, Oct 3, 2006
    #7
  8. Eye Matz

    MonkeeSage Guest

    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
    MonkeeSage, Oct 3, 2006
    #8
  9. Eye Matz

    Eye Matz Guest

    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-forum.com/.
    Eye Matz, Oct 3, 2006
    #9
  10. Eye Matz

    Eye Matz Guest

    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-forum.com/.
    Eye Matz, Oct 3, 2006
    #10
  11. Eye Matz

    Jean Helou Guest

    On 10/3/06, Eye Matz <> 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-forum.com/.
    >
    >

    Maybe this will help since he asked himself the exact same question :
    http://wanderingbarque.com/ruby/DynamicRuby.html

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

    jean
    Jean Helou, Oct 3, 2006
    #11
  12. Eye Matz

    Eye Matz Guest

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


    Hi Tim,

    Thanks for your reply. Yes, I've tried Why's Guide about 30 times by
    now, but I seriously lack a sense of humor it seems, or at least his
    kind of humor.

    I learn best by real life code examples that has plenty of comments
    attached, so I can grep the logic within each line of the execution, and
    I'm fairly certain I'm not alone in that.

    Perhaps someone some day could create a Distilled version of Why's
    Guide, for the rest of us?

    --
    Posted via http://www.ruby-forum.com/.
    Eye Matz, Oct 3, 2006
    #12
  13. Eye Matz

    Eye Matz Guest

    Eye Matz, Oct 3, 2006
    #13
  14. Eye Matz

    Eye Matz Guest

    Jordan Callicoat wrote:
    > Since you asked for a fundimental level explaination I hope this helps
    > and doesn't seem pretentious:


    <SNIP>

    > 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. ;)


    Wow ! Thanks for taking the time Jordan, and all I can say is: "When
    is your book being published ? I'll buy two copies."

    --
    Posted via http://www.ruby-forum.com/.
    Eye Matz, Oct 3, 2006
    #14
  15. Eye Matz

    MonkeeSage Guest

    Eye Matz wrote:
    > Wow ! Thanks for taking the time Jordan, and all I can say is: "When
    > is your book being published ? I'll buy two copies."


    LOL! Well, it would be a very short book since that's about the extent
    of my knowledge, heh! David Black <from this very thread> has a book on
    ruby out there [1], and he's a pretty smart dude. ;)

    [1] http://www.manning.com/black/

    Regards,
    Jordan
    MonkeeSage, Oct 3, 2006
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nick Wouters
    Replies:
    1
    Views:
    537
    Kevin Spencer
    May 27, 2005
  2. Damien Sawyer

    Newbie Question re CSS 'classes' and #

    Damien Sawyer, Aug 16, 2004, in forum: HTML
    Replies:
    7
    Views:
    425
  3. Klaus Oberpichler

    Newbie question on self in classes

    Klaus Oberpichler, Jan 10, 2004, in forum: Python
    Replies:
    1
    Views:
    297
    Peter Otten
    Jan 10, 2004
  4. August0866
    Replies:
    1
    Views:
    109
    Sebastian Hungerecker
    Mar 17, 2008
  5. Jerry C.
    Replies:
    8
    Views:
    215
    Uri Guttman
    Nov 23, 2003
Loading...

Share This Page