One More Bias (or perhaps I'm too novice )

Hi All
Another Query To bother you all:

1 class Person
2 def *(o)
3 puts “One person meets another”
4 end
5
6 def meets (o)
7 puts “One person meets another”
8 end
9 end

10 a= Person.new
11 b=Person.new
12
13 a * b
14 a.meets b

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
now with above Class the output is:

ruby yet.rb
One person meets another
One person meets another

CASE 1
If I replace Line 13 with this:
a % b #(or any other operator i.e. $ ^ & et al.)

I get the following error :
yet.rb:16: undefined method `%’ for #Person:0x282dbf4 (NoMethodError)

CASE 2
But when i replaced Line 14 with this:
a meets b
the error was this

ruby yet.rb
One person meets another
yet.rb:17: warning: parenthesize argument(s) for future version
yet.rb:17: undefined method `meets’ for main:Object (NoMethodError)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
THE QUERY

If a method is encountered then what is order for locating the method
in class hierarchy?
I mean base to child or reverse?

And regardless of that order why ruby tries to locate the “%” method
from Person (case 1)

while the “meets” method is searched for in Object (case 2)

Thanks in Advance
Raja

Ruby is beautiful!

On Fri, Jun 01, 2007 at 10:39:23PM +0900, Vin R. wrote:

10 a= Person.new

CASE 1
If I replace Line 13 with this:
a % b #(or any other operator i.e. $ ^ & et al.)

I get the following error :
yet.rb:16: undefined method `%’ for #Person:0x282dbf4 (NoMethodError)

Correct. a % b is syntactic sugar for a.%(b) or a.send(:%, b)

That is, invoke a method called ‘%’ on object ‘a’, passing ‘b’ as the
argument.

CASE 2
But when i replaced Line 14 with this:
a meets b
the error was this

ruby yet.rb
One person meets another
yet.rb:17: warning: parenthesize argument(s) for future version
yet.rb:17: undefined method `meets’ for main:Object (NoMethodError)

If you don’t follow ‘a’ by a dot, then it’s treated as a method name on
the
local object: that is, self.a(…)

So what you have written is

a( meets( b ) )

which has an implicit receiver,

self.a( meets( b ) )

The receiver, self, is a top-level object called “main”. But you have
not
defined methods ‘a’ or ‘meets’ at the top level.

def a(x)
“a:#{x}”
end

def meets(x)
“meets:#{x}”
end

b = “fred”
puts(a meets b) # “a:meets:fred” but with warnings about missing
parens
puts a(meets(b)) # no warnings

Brian.

On 2007-06-01 22:39:23 +0900 (Fri, Jun), Vin R. wrote:

8 end

ruby yet.rb
CASE 2
THE QUERY

If a method is encountered then what is order for locating the method
in class hierarchy?
I mean base to child or reverse?

Always in ‘current’ object, then in its parent and so on.

And regardless of that order why ruby tries to locate the “%” method
from Person (case 1)

while the “meets” method is searched for in Object (case 2)

That’s how hackers learn new languages! I like your style. :slight_smile:

You found the dark side of ruby parser.
In your case, the parser has decided that expression ‘a meets b’
is a call to method ‘Object#a’ of ‘self’ (some ‘main’ object).

That’s the cause of the warning ‘parenthesize argument(s) for future
version’.
First step was to get the values of the parameter, which was ‘meets b’,
which got understood as a call to Object#meets with parameter ‘b’.
The ‘b’ has been taken as a local variable, because of assignment in
line 11. Having the value of ‘b’ the call to Object#meets has been
executed, which generated the exception.

In the expression ‘a % b’ the ‘%’ has been at once recognized as an
operator, so the corresponding method has been called on the left side
of that operator, thus the error - undefined method on Person.

In other words, the parser had decided that
‘a % b’ is:
‘operator % with arguments “a” and “b”’, which is equal to:
‘a.%(b)’

and

in ‘a meets b’ meets is not an operator, so it’s a function argument,
so ‘a’ is a method call, and there is no ‘meets’ variable (since there
was no assignment seen), so ‘meets’ is also a method call,
and it needs parentheses, so the result was:
‘a( meets(b) )’, which is:
‘self.a( self.meets(b))’, and self.class is Object.