Redefine modules?

Discussion in 'Ruby' started by Stanley Roberts, Feb 11, 2009.

  1. Hi,
    I am quite new to Ruby and make some experiences with modules and
    classes.
    I have defined a module and an inner class with the same name (Cucc) and
    a static method (x) for the class. Then I made a redefinition (or
    whatever you call) of the same module (Cucc) without the inner class but
    with a static (x) method.

    Before the redefinition x method of the Cucc module's inner class Cucc
    is called but right after the modules static method is called. Why?

    I totally agree that coding style like below is among the first 10 on
    the list to avoid during programming, but though I want to understand
    the behavior!

    I have created the following code:
    ------CODE START-----------
    module Cucc
    def Cucc.x(arg)
    puts arg.to_s + " Cucc.x"
    end
    def x(arg)
    puts arg.to_s + " Cucc module x"
    end
    class Cucc
    def Cucc.x(arg)
    puts arg.to_s + " Cucc module Cucc class Cucc.x"
    end
    def x(arg)
    puts arg.to_s + " Cucc module Cucc class x"
    end
    end
    end

    puts "Cucc class started first"
    Cucc::x(10)
    c = Cucc::Cucc.new
    c.x(20)
    Cucc::Cucc.x(30)
    puts "Cucc class ended first"

    module Cucc
    def Cucc.x(arg)
    puts arg.to_s + " Redefined Cucc module Cucc.x"
    end
    def x(arg)
    puts arg.to_s + " Redefined Cucc module x"
    end
    end

    puts "Cucc class started second"
    Cucc::x(10)
    c = Cucc::Cucc.new
    c.x(20)
    Cucc::Cucc.x(30)
    puts "Cucc class ended second"
    ------CODE END-----------

    The outcome is the following:
    Cucc class started first
    10 Cucc.x
    20 Cucc module Cucc class x
    30 Cucc module Cucc class Cucc.x
    Cucc class ended first
    Cucc class started second
    10 Cucc.x
    20 Cucc module Cucc class x
    30 Redefined Cucc module Cucc.x
    Cucc class ended second

    How the hell is it possible that for the "30" that I get different
    result when having a redefinition (or so) of the Cucc module?

    At first the inner class' static method is called and in the second case
    the static method of the module!

    Thanks in advanced, --stan--
    --
    Posted via http://www.ruby-forum.com/.
     
    Stanley Roberts, Feb 11, 2009
    #1
    1. Advertising

  2. Stanley Roberts

    Pit Capitain Guest

    2009/2/11 Stanley Roberts <>:
    > I am quite new to Ruby and make some experiences with modules and
    > classes. (...)


    Stan, maybe the following code will give you some hints:

    module Cucc
    puts Cucc.class # => Module
    class Cucc; end
    puts Cucc.class # => Class
    end

    It has to do with the way Ruby resolves the names of constants.

    Regards,
    Pit
     
    Pit Capitain, Feb 11, 2009
    #2
    1. Advertising

  3. Pit Capitain wrote:
    > 2009/2/11 Stanley Roberts <>:
    >> I am quite new to Ruby and make some experiences with modules and
    >> classes. (...)

    >
    > Stan, maybe the following code will give you some hints:
    >
    > module Cucc
    > puts Cucc.class # => Module
    > class Cucc; end
    > puts Cucc.class # => Class
    > end
    >
    > It has to do with the way Ruby resolves the names of constants.
    >
    > Regards,
    > Pit


    Hi Pit,
    it's OK, but I still don't understand what is the situation when
    overriding a module.

    I have added the class method to check what happens:
    Cucc::Cucc.x(30) # => 30 Cucc module Cucc class Cucc.x
    puts Cucc::Cucc # => Class

    But after the redefinition of the same module (without having the Cucc
    innerclass) the same lines lead to different outcome:
    Cucc::Cucc.x(30) # => 30 Redefined Cucc module Cucc.x
    puts Cucc::Cucc # => Class

    Can you please explain me this?

    Thanks in advance --stan--
    --
    Posted via http://www.ruby-forum.com/.
     
    Stanley Roberts, Feb 12, 2009
    #3
  4. [Note: parts of this message were removed to make it a legal post.]

    On Thu, Feb 12, 2009 at 8:11 AM, Stanley Roberts <
    > wrote:

    > Pit Capitain wrote:
    > > 2009/2/11 Stanley Roberts <>:
    > >> I am quite new to Ruby and make some experiences with modules and
    > >> classes. (...)

    > >
    > > Stan, maybe the following code will give you some hints:
    > >
    > > module Cucc
    > > puts Cucc.class # => Module
    > > class Cucc; end
    > > puts Cucc.class # => Class
    > > end
    > >
    > > It has to do with the way Ruby resolves the names of constants.
    > >
    > > Regards,
    > > Pit

    >
    > Hi Pit,
    > it's OK, but I still don't understand what is the situation when
    > overriding a module.
    >
    > I have added the class method to check what happens:
    > Cucc::Cucc.x(30) # => 30 Cucc module Cucc class Cucc.x
    > puts Cucc::Cucc # => Class
    >
    > But after the redefinition of the same module (without having the Cucc
    > innerclass) the same lines lead to different outcome:
    > Cucc::Cucc.x(30) # => 30 Redefined Cucc module Cucc.x
    > puts Cucc::Cucc # => Class
    >
    > Can you please explain me this?



    You've got two or three misconceptions here.

    First, you seem to assume that redefining a method won't lead to a different
    outcome. Why else would you redefine a method? In ruby redefining a method
    replaces that method, so you'll get the new version when you invoke it. So
    the real question is why aren't you seeing the OTHER redefinition, which is
    the second misconception.

    Second, in your test code you are never calling the second x method. This
    method will only be accessible in an instance of a class which includes the
    Cucc module. So you might want to add

    class Test
    include Cucc
    end

    test = Test.new
    before your "started first"

    and then add test.x(40) to each of your sets of calls, this should show that
    when you call it you do get the redefined method.

    Now, what might seem strange is that you might think that it should be the
    Cucc::x(10)

    which invokes the other redefined method, after all first you wrote:

    module Cucc
    def Cucc.x(...
    end

    and wrote the same thing in the redefinition, this is the third
    misconception, that the meaning of Cucc WITHIN the module means the same
    thing in both cases, it doesn't.

    I'm not sure whether or not you are really confused about this is because of
    the string produced in the overriden method. I'm not sure whether you are
    documenting your intention or your surprise with the result.

    The way Ruby resolves 'global' names is that it starts looking for the name
    in the current module, and if it doesn't find it, it looks for the same name
    in the enclosing name scope.

    So in this case, it will first look for ::Cucc::Cucc (where the initial ::
    indicates the outermost name scope), then it will look for ::Cucc

    The first time, before what you are calling the inner class (which by the
    way is a Java concept not directly transferrable to Ruby) doesn't exist, so
    it doesn't find ::Cucc::Cucc and you end up defining a singleton method of
    the Cucc module.

    The second time, it does find ::Cucc::Cucc so you end up redefining the
    instance method x in Cucc::Cucc.

    If you really wanted to redefine the ::Cucc#x you should right the
    redefinition as either:

    module Cucc
    def self.x(arg)
    puts arg.to_s + " Redefined Cucc module.x"
    end
    #...
    end

    or outside of the module reopening

    def Cucc.x(arg)
    puts arg.to_s + " Redefined Cucc module.x"
    end


    HTH

    --
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Twitter: http://twitter.com/RickDeNatale
     
    Rick DeNatale, Feb 12, 2009
    #4
  5. Stanley Roberts

    Pit Capitain Guest

    2009/2/12 Rick DeNatale <>:
    > (...)
    > and wrote the same thing in the redefinition, this is the third
    > misconception, that the meaning of Cucc WITHIN the module means the same
    > thing in both cases, it doesn't.
    > (...)


    Thanks Rick for the detailed explanation. As you know I've been too
    involved in some other threads lately :)

    Regards,
    Pit
     
    Pit Capitain, Feb 12, 2009
    #5
    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. Michael Bane
    Replies:
    0
    Views:
    608
    Michael Bane
    Sep 11, 2003
  2. Fernando Martins

    Redefine entities in XSL.

    Fernando Martins, Oct 1, 2003, in forum: XML
    Replies:
    0
    Views:
    467
    Fernando Martins
    Oct 1, 2003
  3. BillD
    Replies:
    2
    Views:
    843
    BillD
    Oct 4, 2004
  4. Cat
    Replies:
    1
    Views:
    562
  5. Nafai
    Replies:
    4
    Views:
    351
    James Rafter
    Dec 8, 2004
Loading...

Share This Page