Method Precedence

Hello all,

If I have a class such as:

class Example

  def one
    puts "one"

    def two
      puts "two inside one"
    end
  end

  def two
    puts "two inside Example"
  end

end

And I do:
e = Example.new
e.one
e.two

I get, obviously:
one
two inside one

What I don't understand is that if after that I do:
f = Example.new
f.two

I still get:
two inside one

Since the two method in question is defined within one, doesn't it
behave like a method on the object e? How can it override the two
method outside for the f object?

Thanks for your help in explaining this.

Daly wrote:

Hello all,

If I have a class such as:

class Example

  def one
    puts "one"

    def two
      puts "two inside one"
    end
  end

  def two
    puts "two inside Example"
  end

end

And I do:
e = Example.new
e.one
e.two

I get, obviously:
one
two inside one

What I don't understand is that if after that I do:
f = Example.new
f.two

I still get:
two inside one

When the compiler first encountered Example, it plugged one() and the outer two() into Example's class instance list.

The first call to one() then bonds the inner two() to the class. The object did not get affected in either case. (Always remember classes are objects around here!)

If you ran the program again (a new Ruby "VM"), and never called one(), you would only get the outer two().

···

--
   Phlip

What happens when you call the one method is it redefines the two INSTANCE METHOD at the class level (ie the context of instance method definition in the class), which means ALL objects are affected.

Why would you want to do this?

Julian.

···

On 06/02/2009, at 2:05 PM, Daly wrote:

Hello all,

If I have a class such as:

class Example

def one
   puts "one"

   def two
     puts "two inside one"
   end
end

def two
   puts "two inside Example"
end

end

And I do:
e = Example.new
e.one
e.two

I get, obviously:
one
two inside one

What I don't understand is that if after that I do:
f = Example.new
f.two

I still get:
two inside one

Since the two method in question is defined within one, doesn't it
behave like a method on the object e? How can it override the two
method outside for the f object?

Thanks for your help in explaining this.

In case you just want to influence the e object, say

  class Example
    def one
      puts "one"
      def self.two
  # ^^^^^
        puts "two inside one"
      end
    end
  end

Bertram

···

Am Freitag, 06. Feb 2009, 12:05:21 +0900 schrieb Daly:

class Example
  def one
    puts "one"
    def two
      puts "two inside one"
    end
  end
  def two
    puts "two inside Example"
  end
end

e = Example.new
e.one
e.two
f = Example.new
f.two

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

FYI, it's not a compiler, it's an interpreter.

Also, by "the object did not get affected" you mean the instance object... just to clarify for him.

Julian.

···

On 06/02/2009, at 2:19 PM, Phlip wrote:

When the compiler first encountered Example, it plugged one() and the outer two() into Example's class instance list.

The first call to one() then bonds the inner two() to the class. The object did not get affected in either case. (Always remember classes are objects around here!)

If you ran the program again (a new Ruby "VM"), and never called one(), you would only get the outer two().

I'm doing this as a learning experiment. I would have thought that
since self inside method one is an object, then two inside one would
be defined on the object, not on the class.

Phlip's explanation made it clear to me though. It's as if I opened
the class and redefined two, correct?

···

On Feb 5, 10:26 pm, Julian Leviston <jul...@coretech.net.au> wrote:

What happens when you call the one method is it redefines the two
INSTANCE METHOD at the class level (ie the context of instance method
definition in the class), which means ALL objects are affected.

Why would you want to do this?

Julian.

On 06/02/2009, at 2:05 PM, Daly wrote:

> Hello all,

> If I have a class such as:

> class Example

> def one
> puts "one"

> def two
> puts "two inside one"
> end
> end

> def two
> puts "two inside Example"
> end

> end

> And I do:
> e = Example.new
> e.one
> e.two

> I get, obviously:
> one
> two inside one

> What I don't understand is that if after that I do:
> f = Example.new
> f.two

> I still get:
> two inside one

> Since the two method in question is defined within one, doesn't it
> behave like a method on the object e? How can it override the two
> method outside for the f object?

> Thanks for your help in explaining this.

Yeah that's a much better way to do it than instance_eval!

Julian

···

On 06/02/2009, at 3:22 PM, Bertram Scharpf wrote:

Am Freitag, 06. Feb 2009, 12:05:21 +0900 schrieb Daly:

class Example
def one
   puts "one"
   def two
     puts "two inside one"
   end
end
def two
   puts "two inside Example"
end
end

e = Example.new
e.one
e.two
f = Example.new
f.two

In case you just want to influence the e object, say

class Example
   def one
     puts "one"
     def self.two
# ^^^^^
       puts "two inside one"
     end
   end
end

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

Julian Leviston wrote:

FYI, it's not a compiler, it's an interpreter.

The terms "compiler" and "interpreter" have never been exclusive - ask a Lisper!

···

--
   Phlip

Daly wrote:

Phlip's explanation made it clear to me though. It's as if I opened
the class and redefined two, correct?

Yes - always think of the interpreter like a text caret skipping thru the program, statement by statement, from top to bottom. It interprets 'class' and 'def', but it only parses what's inside the def, and stores it. The interpreter can't even see the inner 'too()' (except as lexically correct tokens). Only when you call 'one()' does the interpreter go back inside and this time actually execute its lines.

No

The method is on the class, as an istnce method. There is only one class, and all instances look to it for their methods. If you want you can do methods on particular instances only. You probably want this behaviour and I think it's achieved with instance_eval. I'll post an example in a sec

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

···

On 06/02/2009, at 2:46 PM, Daly <aeldaly@gmail.com> wrote:

I'm doing this as a learning experiment. I would have thought that
since self inside method one is an object, then two inside one would
be defined on the object, not on the class.

Phlip's explanation made it clear to me though. It's as if I opened
the class and redefined two, correct?

On Feb 5, 10:26 pm, Julian Leviston <jul...@coretech.net.au> wrote:

What happens when you call the one method is it redefines the two
INSTANCE METHOD at the class level (ie the context of instance method
definition in the class), which means ALL objects are affected.

Why would you want to do this?

Julian.

On 06/02/2009, at 2:05 PM, Daly wrote:

Hello all,

If I have a class such as:

class Example

def one
   puts "one"

   def two
     puts "two inside one"
   end
end

def two
   puts "two inside Example"
end

end

And I do:
e = Example.new
e.one
e.two

I get, obviously:
one
two inside one

What I don't understand is that if after that I do:
f = Example.new
f.two

I still get:
two inside one

Since the two method in question is defined within one, doesn't it
behave like a method on the object e? How can it override the two
method outside for the f object?

Thanks for your help in explaining this.

Yeah, it's as if you opened the class and redefined two... you're right.

if you want to define the method only on the particular instance that you run that one method on you can do something like this:

hope this helps.

Last login: Fri Feb 6 14:06:35 on ttys003
Phatty:~ julian$ irb
>> class Hi
>> def one
>> instance_eval("
def two
puts 'hi'
end
")
>> end
>> def two
>> puts 'woo'
>> end
=> nil
>> x = Hi.new
=> #<Hi:0x5eab78>
>> y = Hi.new
=> #<Hi:0x5e96b0>
>> x.two
woo
=> nil
>> y.two
woo
=> nil
>> x.one
=> nil
>> x.two
hi
=> nil
>> y.two
woo
=> nil

···

On 06/02/2009, at 2:46 PM, Daly wrote:

I'm doing this as a learning experiment. I would have thought that
since self inside method one is an object, then two inside one would
be defined on the object, not on the class.

Phlip's explanation made it clear to me though. It's as if I opened
the class and redefined two, correct?

On Feb 5, 10:26 pm, Julian Leviston <jul...@coretech.net.au> wrote:

What happens when you call the one method is it redefines the two
INSTANCE METHOD at the class level (ie the context of instance method
definition in the class), which means ALL objects are affected.

Why would you want to do this?

Julian.

On 06/02/2009, at 2:05 PM, Daly wrote:

Hello all,

If I have a class such as:

class Example

def one
   puts "one"

   def two
     puts "two inside one"
   end
end

def two
   puts "two inside Example"
end

end

And I do:
e = Example.new
e.one
e.two

I get, obviously:
one
two inside one

What I don't understand is that if after that I do:
f = Example.new
f.two

I still get:
two inside one

Since the two method in question is defined within one, doesn't it
behave like a method on the object e? How can it override the two
method outside for the f object?

Thanks for your help in explaining this.

Daly <aeldaly@gmail.com> writes:

I'm doing this as a learning experiment. I would have thought that
since self inside method one is an object, then two inside one would
be defined on the object, not on the class.

Phlip's explanation made it clear to me though. It's as if I opened
the class and redefined two, correct?

Yes.

def ... end is not a definition. It's an expression. It is executed,
and it has side effects.

···

--
__Pascal Bourguignon__

Thank you all for a very informative thread.

···

On Feb 5, 11:31 pm, Julian Leviston <jul...@coretech.net.au> wrote:

Yeah that's a much better way to do it than instance_eval!

Julian

On 06/02/2009, at 3:22 PM, Bertram Scharpf wrote:

> Am Freitag, 06. Feb 2009, 12:05:21 +0900 schrieb Daly:
>> class Example
>> def one
>> puts "one"
>> def two
>> puts "two inside one"
>> end
>> end
>> def two
>> puts "two inside Example"
>> end
>> end

>> e = Example.new
>> e.one
>> e.two
>> f = Example.new
>> f.two

> In case you just want to influence the e object, say

> class Example
> def one
> puts "one"
> def self.two
> # ^^^^^
> puts "two inside one"
> end
> end
> end

> Bertram

> --
> Bertram Scharpf
> Stuttgart, Deutschland/Germany
>http://www.bertram-scharpf.de

Ah, okay. So Ruby is a compiled language is it?

Generally, compilation is when you take all of your resources and build a product (in every sense of the definition). Interpretation is when moment by moment, you translate bits as they come in.

Don't confuse the beginners!!!!!

<grrrr>

Yeah, like saying "translator" instead of "interpreter" when talking natural (human) languages.

J

···

On 06/02/2009, at 2:49 PM, Phlip wrote:

Julian Leviston wrote:

FYI, it's not a compiler, it's an interpreter.

The terms "compiler" and "interpreter" have never been exclusive - ask a Lisper!

--
Phlip