Method Precedence

D

Daly

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.
 
P

Phlip

Daly said:
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().
 
J

Julian Leviston

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.
 
J

Julian Leviston

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.
 
D

Daly

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?
 
P

Phlip

Daly said:
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.
 
J

Julian Leviston

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/
 
J

Julian Leviston

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$ irbdef two
puts 'hi'
end
")woo
=> nilwoo
=> nilhi
=> nilwoo
=> nil
 
B

Bertram Scharpf

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
 
P

Pascal J. Bourguignon

Daly said:
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.
 
J

Julian Leviston

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
 
M

Mike Gold

def inside def: "It's undocumented and should not be used nor touched."
http://redmine.ruby-lang.org/issues/show/797

Also, there is nothing gained with def inside def. It is equivalent to
adding a method to the singleton class, but without the ability to
reference variables from the enclosing binding.

class A
def f
x = 3
# note: Object#singleton_class makes this cleaner
(class << self ; self ; end).instance_eval {
define_method:)g) {
puts x
}
}
end
end

a = A.new
a.f
a.g #=> 3

class B
def f
x = 9
def g
puts x
end
end
end

b = B.new
b.f
b.g #=> undefined local variable or method `x'
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,979
Messages
2,570,185
Members
46,723
Latest member
TwilaTarde

Latest Threads

Top