include and extend Module - Ruby Way

Discussion in 'Ruby' started by Alexandru Popescu, Aug 21, 2005.

  1. Hi!

    I am reading the excellent The Ruby Way. I most probably not understand correctly the following pieces:

    [quote page=38]
    With include, the module's methods become available as instance methods; with extend, they become
    available as class methods
    [/quote]

    I have written the following code example:

    Code:
    module ExampleModule
    def moduleMethod
    puts 'module method'
    end
    end
    
    class IncludeModule
    include ExampleModule
    end
    
    class ExtendModule
    extend ExampleModule
    end
    
    im = IncludeModule.new
    # IncludeModule.moduleMethod # this is correct
    im.moduleMethod # module method becomes instance method
    
    em = ExtendModule.new
    ExtendModule.moduleMethod # module method becomes class method
    em.moduleMethod # this is failing! WHY?
    
    As pointed above the em#moduleMethod is failing. Being a class method I expect it to be available
    also on every instance. What I wrongly understood?

    Later I can read the following:

    [quote page=275]
    The extend method will mix a module into an object. The instance methods from the module become
    instance methods for the object.
    [/quote]

    Isn't this in contradiction with the first quote?

    Please enlighten me.

    :alex |.::the_mindstorm::.|
    Alexandru Popescu, Aug 21, 2005
    #1
    1. Advertising

  2. Alexandru Popescu

    Paul Guest

    It is a Class method so you'd go

    irb>ExtendModule::moduleMethod
    module method
    Paul, Aug 21, 2005
    #2
    1. Advertising

  3. Alexandru Popescu wrote:
    > As pointed above the em#moduleMethod is failing. Being a class method I expect it to be available
    > also on every instance. What I wrongly understood?


    Class methods are members of the class, not of instances of the class.
    For instance, Object.new calls the class method new of Object, but you
    can't do Object.new.new, because new is not an instance method.

    > Later I can read the following:
    >
    > [quote page=275]
    > The extend method will mix a module into an object. The instance methods from the module become
    > instance methods for the object.
    > [/quote]
    >
    > Isn't this in contradiction with the first quote?


    The first quote had to do with classes; this one is talking about
    instances. Telling an object "extend SomeModule" tells it to add the
    methods in SomeModule to itself. In the case of a class, these will
    become methods of that class. In the case of a class instance, they
    will become methods of that instance.

    Does that make more sense?
    Charles Steinman, Aug 21, 2005
    #3
  4. #: Charles Steinman changed the world a bit at a time by saying on 8/21/2005 9:51 AM :#
    > Alexandru Popescu wrote:
    >> As pointed above the em#moduleMethod is failing. Being a class method I expect it to be available
    >> also on every instance. What I wrongly understood?

    >
    > Class methods are members of the class, not of instances of the class.
    > For instance, Object.new calls the class method new of Object, but you
    > can't do Object.new.new, because new is not an instance method.
    >


    Thanks Charles. I start to see the end tunnel light. It is the same as:

    Code:
    class ClassExample
    def ClassExample.do_something
    p "class method too"
    end
    end
    
    ClassExample.do_something # class method too
    cls= ClassExample.new
    cls.do_something # => NoMethodError
    
    Coming from the Java world, for me a class method is a (static) method available withouth a self
    (this) reference, but it is available/callable from any instance. (is this available in Ruby?)

    It seems that in Ruby the class method is a method belonging to the class ClassExample object.

    How can I avoid this term confusion? (at least in my head).

    :alex |.::the_mindstorm::.|

    >> Later I can read the following:
    >>
    >> [quote page=275]
    >> The extend method will mix a module into an object. The instance methods from the module become
    >> instance methods for the object.
    >> [/quote]
    >>
    >> Isn't this in contradiction with the first quote?

    >
    > The first quote had to do with classes; this one is talking about
    > instances. Telling an object "extend SomeModule" tells it to add the
    > methods in SomeModule to itself. In the case of a class, these will
    > become methods of that class. In the case of a class instance, they
    > will become methods of that instance.
    >
    > Does that make more sense?
    >
    >
    >
    Alexandru Popescu, Aug 21, 2005
    #4
  5. On Aug 21, 2005, at 3:11 AM, Alexandru Popescu wrote:
    > Coming from the Java world, for me a class method is a (static)
    > method available withouth a self (this) reference, but it is
    > available/callable from any instance. (is this available in Ruby?)


    Sorry, I don't know Java (any more). Are you describing a global
    function that is only available to instance methods of a certain
    class, which is invoked without an explicit receiver?

    Something like:
    class Foo
    def foo_m
    x = my_utility_function( )
    end
    end

    class Bar
    def bar_m
    x = my_utility_function( )
    end
    end

    f = Foo.new
    f.foo_m #works

    b = Bar.new
    b.bar_m #raises an error because my_utility_function() isn't
    available to Bar instances


    > It seems that in Ruby the class method is a method belonging to the
    > class ClassExample object.


    Yup, that's the case. Classes are objects too. So you can do:

    class Foo
    def self.upcount #same as def Foo.upcount
    @instances ||= 0
    @instances += 1
    end

    def self.getcount
    @instances
    end


    def initialize
    self.class.upcount
    end

    def count_neighbors
    self.class.getcount
    end
    end

    f1 = Foo.new
    f2 = Foo.new
    f3 = Foo.new
    p f1.count_neighbors #=> 3


    As you can see above, the Class has its own scope for its own
    instance variable. The class itself is a completely separate instance
    of the "Class" class, which just happens to be tied to instances of
    it in a few special ways.
    Gavin Kistner, Aug 21, 2005
    #5
  6. #: Gavin Kistner changed the world a bit at a time by saying on 8/21/2005 4:36 PM :#
    > On Aug 21, 2005, at 3:11 AM, Alexandru Popescu wrote:
    >> Coming from the Java world, for me a class method is a (static)
    >> method available withouth a self (this) reference, but it is
    >> available/callable from any instance. (is this available in Ruby?)

    >
    > Sorry, I don't know Java (any more). Are you describing a global
    > function that is only available to instance methods of a certain
    > class, which is invoked without an explicit receiver?
    >


    Nope. I was talking about:
    Code:
    public class ExampleClass {
    public static void staticMethod() {
    // illegal access to any instance field
    System.out.println("staticMethod");
    }
    }
    
    ExampleClass.staticMethod(); // prints the message; no instance of ExampleClass is available
    ExampleClass ec= new ExampleClass();
    ec.staticMethod(); // prints the message; not recommended but works
    [color=blue]
    >
    >[color=green]
    >> It seems that in Ruby the class method is a method belonging to the
    >> class ClassExample object.[/color]
    >
    > Yup, that's the case. Classes are objects too. So you can do:
    >
    > class Foo
    >      def self.upcount   #same as def Foo.upcount
    >          @instances ||= 0
    >          @instances += 1
    >      end
    >
    >      def self.getcount
    >          @instances
    >      end
    >
    >
    >      def initialize
    >          self.class.upcount
    >      end
    >
    >      def count_neighbors
    >          self.class.getcount
    >      end
    > end
    >
    > f1 = Foo.new
    > f2 = Foo.new
    > f3 = Foo.new
    > p f1.count_neighbors #=> 3
    >
    >
    > As you can see above, the Class has its own scope for its own
    > instance variable. The class itself is a completely separate instance
    > of the "Class" class, which just happens to be tied to instances of
    > it in a few special ways.
    >[/color]
    
    Writting some more examples I think I got the idea. It is subtle difference that I don't know how to
    describe in words :-s. (the class method in Ruby belongs only to the new defined class, but not to
    its instances, while in Java the class method belongs to the new defined class and all its instances).
    
    :alex |.::the_mindstorm::.|
    Alexandru Popescu, Aug 21, 2005
    #6
  7. On Aug 21, 2005, at 9:04 AM, Alexandru Popescu wrote:
    >> Sorry, I don't know Java (any more). Are you describing a global
    >> function that is only available to instance methods of a certain
    >> class, which is invoked without an explicit receiver?
    >>

    >
    > Nope. I was talking about:
    >
    Code:
    > public class ExampleClass {
    >     public static void staticMethod() {
    >         // illegal access to any instance field
    >         System.out.println("staticMethod");
    >     }
    > }
    >
    > ExampleClass.staticMethod(); // prints the message; no instance of
    > ExampleClass is available
    > ExampleClass ec= new ExampleClass();
    > ec.staticMethod(); // prints the message; not recommended but works[/color]
    
    I don't know of a built-in mechanism to do this in Ruby, other than
    something like:
    
    class Foo
    def self.staticMethod
    puts "staticMethod"
    end
    def staticMethod
    self.class.staticMethod
    end
    end
    
    There are things you could do to make it easier to set this up, so
    you might only have to type something like:
    class Foo
    static_method :foo {
    # your_code_here
    }
    end
    but that would just be a fancy interface to setting up a method on
    both the class and its instances.
    
    
    You say that it's not recommended, so I gather this isn't a big
    issue. Is there some specific use case where you find this useful?
    Gavin Kistner, Aug 21, 2005
    #7
  8. #: Gavin Kistner changed the world a bit at a time by saying on 8/21/2005 7:29 PM :#
    > On Aug 21, 2005, at 9:04 AM, Alexandru Popescu wrote:
    >>> Sorry, I don't know Java (any more). Are you describing a global
    >>> function that is only available to instance methods of a certain
    >>> class, which is invoked without an explicit receiver?
    >>>

    >>
    >> Nope. I was talking about:
    >>
    Code:
    >> public class ExampleClass {
    >>     public static void staticMethod() {
    >>         // illegal access to any instance field
    >>         System.out.println("staticMethod");
    >>     }
    >> }
    >>
    >> ExampleClass.staticMethod(); // prints the message; no instance of
    >> ExampleClass is available
    >> ExampleClass ec= new ExampleClass();
    >> ec.staticMethod(); // prints the message; not recommended but works[/color]
    >
    > I don't know of a built-in mechanism to do this in Ruby, other than
    > something like:
    >
    > class Foo
    >      def self.staticMethod
    >          puts "staticMethod"
    >      end
    >      def staticMethod
    >          self.class.staticMethod
    >      end
    > end
    >
    > There are things you could do to make it easier to set this up, so
    > you might only have to type something like:
    > class Foo
    >      static_method :foo {
    >          # your_code_here
    >      }
    > end
    > but that would just be a fancy interface to setting up a method on
    > both the class and its instances.
    >
    >
    > You say that it's not recommended, so I gather this isn't a big
    > issue. Is there some specific use case where you find this useful?
    >
    >[/color]
    
    Actually I was trying to clarify my mind. No, I am not gonna use such a thing (taking into account
    that however it is wrong).
    
    :alex |.::the_mindstorm::.|
    Alexandru Popescu, Aug 21, 2005
    #8
  9. Hi --

    On Mon, 22 Aug 2005, Gavin Kistner wrote:

    > On Aug 21, 2005, at 9:04 AM, Alexandru Popescu wrote:
    >>> Sorry, I don't know Java (any more). Are you describing a global function
    >>> that is only available to instance methods of a certain class, which is
    >>> invoked without an explicit receiver?
    >>>

    >>
    >> Nope. I was talking about:
    >>
    Code:
    >> public class ExampleClass {
    >>     public static void staticMethod() {
    >>         // illegal access to any instance field
    >>         System.out.println("staticMethod");
    >>     }
    >> }
    >>
    >> ExampleClass.staticMethod(); // prints the message; no instance of
    >> ExampleClass is available
    >> ExampleClass ec= new ExampleClass();
    >> ec.staticMethod(); // prints the message; not recommended but works[/color]
    >
    > I don't know of a built-in mechanism to do this in Ruby, other than something
    > like:
    >
    > class Foo
    >    def self.staticMethod
    >        puts "staticMethod"
    >    end
    >    def staticMethod
    >        self.class.staticMethod
    >    end
    > end[/color]
    
    You could do:
    
    class C
    module M
    def x
    puts "'Static'?  Nothing is 'static' in Ruby :-)"
    end
    end
    
    include M     # for instances of C
    extend M      # for C itself
    end
    
    C.x
    C.new.x
    
    
    David
    
    --
    David A. Black
    
    David A. Black, Aug 21, 2005
    #9
  10. >
    >
    >>> ExampleClass.staticMethod(); // prints the message; no instance of
    >>> ExampleClass is available
    >>> ExampleClass ec= new ExampleClass();
    >>> ec.staticMethod(); // prints the message; not recommended but works

    >>

    Here's another way:

    class Object
    alias_method :eek:rig_method_missing, :method_missing
    def method_missing(*a,&b)
    self.class.send *a,&b
    end
    end

    class Class
    def method_missing(*a,&b); orig_method_missing(*a,&b) end
    end

    "fun with Ruby".new #=>""
    #w{can we say code smell?}.new #=>[]
    "mwhaowt!".mwhaowt #=>NoMethodError

    Devin
    Devin Mullins, Aug 22, 2005
    #10
    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. =?Utf-8?B?Um9iIEtheQ==?=

    Extend the Membership Provider to include more user data

    =?Utf-8?B?Um9iIEtheQ==?=, Jan 5, 2006, in forum: ASP .Net
    Replies:
    5
    Views:
    7,956
    Scott Allen
    Jan 6, 2006
  2. Andreas Bogenberger
    Replies:
    3
    Views:
    849
    Andreas Bogenberger
    Feb 22, 2008
  3. Gavin Kistner
    Replies:
    5
    Views:
    127
    Robert Klemme
    Oct 23, 2004
  4. Jeff Cohen
    Replies:
    3
    Views:
    115
    Jeff Cohen
    Oct 16, 2006
  5. rlf
    Replies:
    1
    Views:
    79
    Gary Wright
    May 22, 2009
Loading...

Share This Page