[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Top-level

Lucas Holland

5/3/2007 6:13:00 PM

Hello everyone!

I'm currently diving a bit deeper into Ruby and I've already asked this
question in the IRC (the folks there have been great I think I'm getting
it 50%). The question's about top-level methods:

Let's take puts as an example. Puts is inside of the Kernel module,
which gets mixed into the Object class. So essentially, it's a private
method of Object. When I call puts, I don't specify a receiver, so self
is assumed (I think so). In this case self refers to main, an instance
of Object, automatically created. So, I'm really calling main.puts. main
is an instance of Object, so why is it able to call private methods of
Object?


Help would be greatly appreciated!

Lucas

--
Posted via http://www.ruby-....

9 Answers

Robert Klemme

5/3/2007 6:34:00 PM

0

On 03.05.2007 20:13, Lucas Holland wrote:
> I'm currently diving a bit deeper into Ruby and I've already asked this
> question in the IRC (the folks there have been great I think I'm getting
> it 50%). The question's about top-level methods:
>
> Let's take puts as an example. Puts is inside of the Kernel module,
> which gets mixed into the Object class. So essentially, it's a private
> method of Object. When I call puts, I don't specify a receiver, so self
> is assumed (I think so).

Correct.

> In this case self refers to main, an instance
> of Object, automatically created. So, I'm really calling main.puts. main
> is an instance of Object, so why is it able to call private methods of
> Object?

Um, you explained it already: "puts" is an *instance* method of Object.
And since "main" is an instance of Object or one of its subclasses
(all classes are subclasses of Object!) it has method "puts". Basically
the method is only defined private in order to enforce a more function
like invocation:

irb(main):001:0> self.puts "foo"
NoMethodError: private method `puts' called for main:Object
from (irb):1
from :0
irb(main):002:0> puts "foo"
foo
=> nil
irb(main):003:0>

Kind regards

robert

Rick DeNatale

5/3/2007 6:48:00 PM

0

On 5/3/07, Lucas Holland <hollandlucas@gmail.com> wrote:
> Hello everyone!
>
> I'm currently diving a bit deeper into Ruby and I've already asked this
> question in the IRC (the folks there have been great I think I'm getting
> it 50%). The question's about top-level methods:
>
> Let's take puts as an example. Puts is inside of the Kernel module,
> which gets mixed into the Object class. So essentially, it's a private
> method of Object.

Yes

> When I call puts, I don't specify a receiver, so self
> is assumed (I think so).

Yes

> In this case self refers to main, an instance
> of Object, automatically created.

Yes, well it's created when ruby starts up.

> So, I'm really calling main.puts. main
> is an instance of Object, so why is it able to call private methods of
> Object?

You're calling puts in the context of the top-level object. In other
words self is the top-level object in code which is outside any class
or method definitions. The method puts is a private instance method,
so any Object can invoke it as long as the receiver is implicitly
'self':

irb(main):001:0> p self
main
=> nil
irb(main):002:0> puts "foo"
foo
=> nil
irb(main):003:0> self.puts "foo"
NoMethodError: private method `puts' called for main:Object
from (irb):3

Note that the ruby enforces private methods is that you can't
explictily specify a receiver, even self.

Note that IRB treats methods defined at the top level a little
differently, in that they are public rather than private:

irb(main):004:0> def bar
irb(main):005:1> puts "bar"
irb(main):006:1> nil
irb(main):007:1> end
=> nil
irb(main):008:0> bar
bar
=> nil
irb(main):009:0> self.bar
bar
=> nil

But
$ ruby -e'def bar;puts "bar";nil;end;bar;self.bar'
bar
-e:1: private method `bar' called for main:Object (NoMethodError)


> Help would be greatly appreciated!

HTH

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Lucas Holland

5/4/2007 4:52:00 AM

0

Robert Klemme wrote:
> On 03.05.2007 20:13, Lucas Holland wrote:
>> I'm currently diving a bit deeper into Ruby and I've already asked this
>> question in the IRC (the folks there have been great I think I'm getting
>> it 50%). The question's about top-level methods:
>>
>> Let's take puts as an example. Puts is inside of the Kernel module,
>> which gets mixed into the Object class. So essentially, it's a private
>> method of Object. When I call puts, I don't specify a receiver, so self
>> is assumed (I think so).
>
> Correct.
>
>> In this case self refers to main, an instance
>> of Object, automatically created. So, I'm really calling main.puts. main
>> is an instance of Object, so why is it able to call private methods of
>> Object?
>
> Um, you explained it already: "puts" is an *instance* method of Object.
> And since "main" is an instance of Object or one of its subclasses
> (all classes are subclasses of Object!) it has method "puts". Basically
> the method is only defined private in order to enforce a more function
> like invocation:
>
> irb(main):001:0> self.puts "foo"
> NoMethodError: private method `puts' called for main:Object
> from (irb):1
> from :0
> irb(main):002:0> puts "foo"
> foo
> => nil
> irb(main):003:0>
>
> Kind regards
>
> robert

Hey, it's me again (this time I'm logged in ;-) ). I understand that
puts is a private instance method of Object and that thus, all instances
of Object have the method. I also understand that I can only call
private methods if the receiver is self (by not specifying the
receiver). So, in this instance, that's the case. When I however create
a class like so:

class MyClass
private
def test
puts "hello, world"
end
public
def pub
test
end
end

I am able to call the test method because of the implicit receiver,
self. In this case, however, self refers to the class MyClass (which is
an instance of Class, as far as I know). But MyClass is an instance of
Class, not of itself, so why can it suddenly call *instance* methods of
itself?

Thanks in advance,

Lucas

--
Posted via http://www.ruby-....

Brian Candler

5/4/2007 5:48:00 AM

0

On Fri, May 04, 2007 at 01:52:21PM +0900, Lucas Holland wrote:
> receiver). So, in this instance, that's the case. When I however create
> a class like so:
>
> class MyClass
> private
> def test
> puts "hello, world"
> end
> public
> def pub
> test
> end
> end
>
> I am able to call the test method because of the implicit receiver,
> self. In this case, however, self refers to the class MyClass (which is
> an instance of Class, as far as I know).

No. Inside your 'test' method, which is an instance method of MyClass, self
refers to an object which is one particular instance of MyClass.

That is, you can't run it like this:

MyClass.pub

Rather, you have to do

MyClass.new.pub

(the receiver of the message is an *instance* of MyClass that you've
created)

Outside of 'def test', self does indeed refer to the class.

class MyClass
p self # self is 'MyClass'
def test
p self # self is an instance of MyClass
end
end

Lucas Holland

5/4/2007 11:50:00 AM

0

Brian Candler wrote:
> On Fri, May 04, 2007 at 01:52:21PM +0900, Lucas Holland wrote:
>> test
>> end
>> end
>>
>> I am able to call the test method because of the implicit receiver,
>> self. In this case, however, self refers to the class MyClass (which is
>> an instance of Class, as far as I know).
>
> No. Inside your 'test' method, which is an instance method of MyClass,
> self
> refers to an object which is one particular instance of MyClass.
>
> That is, you can't run it like this:
>
> MyClass.pub
>
> Rather, you have to do
>
> MyClass.new.pub
>
> (the receiver of the message is an *instance* of MyClass that you've
> created)
>
> Outside of 'def test', self does indeed refer to the class.
>
> class MyClass
> p self # self is 'MyClass'
> def test
> p self # self is an instance of MyClass
> end
> end

Ah, I see. Okay, so I can call puts like a 'standalone function' because
of the following: When I run a Ruby script, an object called 'main' is
instanciated. It's an instance of the Object class. The Object class
includes puts via a mixin from the Kernel module. It's thus like a
private instance method of Object.

When I call puts, I don't specify a receiver. That's why Ruby takes self
as the receiver. At the top level, self refers to the main object. So my
call is basically main.puts

puts is a *private* instance method of Object, so why can I call it from
an instance (main being the instance in this case)?

Lucas

--
Posted via http://www.ruby-....

dblack

5/4/2007 12:04:00 PM

0

Hi --

On 5/4/07, Lucas Holland <hollandlucas@gmail.com> wrote:
> Brian Candler wrote:
> > On Fri, May 04, 2007 at 01:52:21PM +0900, Lucas Holland wrote:
> >> test
> >> end
> >> end
> >>
> >> I am able to call the test method because of the implicit receiver,
> >> self. In this case, however, self refers to the class MyClass (which is
> >> an instance of Class, as far as I know).
> >
> > No. Inside your 'test' method, which is an instance method of MyClass,
> > self
> > refers to an object which is one particular instance of MyClass.
> >
> > That is, you can't run it like this:
> >
> > MyClass.pub
> >
> > Rather, you have to do
> >
> > MyClass.new.pub
> >
> > (the receiver of the message is an *instance* of MyClass that you've
> > created)
> >
> > Outside of 'def test', self does indeed refer to the class.
> >
> > class MyClass
> > p self # self is 'MyClass'
> > def test
> > p self # self is an instance of MyClass
> > end
> > end
>
> Ah, I see. Okay, so I can call puts like a 'standalone function' because
> of the following: When I run a Ruby script, an object called 'main' is
> instanciated. It's an instance of the Object class. The Object class
> includes puts via a mixin from the Kernel module. It's thus like a
> private instance method of Object.
>
> When I call puts, I don't specify a receiver. That's why Ruby takes self
> as the receiver. At the top level, self refers to the main object. So my
> call is basically main.puts

Except that Ruby makes a pretty huge distinction between meth and
obj.meth (presence or absence of explicit receiver), namely: private
methods have to be called without an explicit receiver.

class C
def x
puts "x"
end
private :x

def y
x # no explicit receiver
end
end

c = C.new
c.y # the call to x takes place inside y, where self is c
c.x # explicit receiver; Ruby won't let you do it

> puts is a *private* instance method of Object, so why can I call it from
> an instance (main being the instance in this case)?

See above. Private doesn't mean you can never call the method :-) It
just means that you have to call it without an explicit receiver,
which essentially translates into: you can call private methods on
self (because you can call methods on self without an explicit
receiver).


David

--
Upcoming Rails training by Ruby Power and Light:
Four-day Intro to Intermediate
May 8-11, 2007
Edison, NJ
http://www.rubypal.com/event...

Lucas Holland

5/4/2007 12:06:00 PM

0

Okay, so I can call puts because I am calling it on self (and self
refers to main, doesn't it?)?

Lucas

--
Posted via http://www.ruby-....

Brian Candler

5/4/2007 6:32:00 PM

0

On Fri, May 04, 2007 at 08:50:01PM +0900, Lucas Holland wrote:
> Ah, I see. Okay, so I can call puts like a 'standalone function' because
> of the following: When I run a Ruby script, an object called 'main' is
> instanciated. It's an instance of the Object class. The Object class
> includes puts via a mixin from the Kernel module. It's thus like a
> private instance method of Object.
>
> When I call puts, I don't specify a receiver. That's why Ruby takes self
> as the receiver. At the top level, self refers to the main object. So my
> call is basically main.puts

Roughly. Except you can't actually call it that way, because it's private.

> puts is a *private* instance method of Object, so why can I call it from
> an instance (main being the instance in this case)?

'Private' means it can *only* be called on self, and only using the implicit
form (where you don't specify a receiver).

HTH,

Brian.

Rick DeNatale

5/5/2007 10:51:00 PM

0

On 5/4/07, Lucas Holland <hollandlucas@gmail.com> wrote:
> Okay, so I can call puts because I am calling it on self (and self
> refers to main, doesn't it?)?

Yes, although the fact that self in this case refers to main is pretty
much irrelevant.

In general, self always refers to SOME object, in top-level code that
object is the top-level object or main.

In an instance method, self is the instance which received the message.

In a class method, self is the class, but Class is a subclass of
Object so classes also inherit the methods of Object, including the
(private) methods defined by Kernel which is included by Object. The
only time you can't if if a class has specifically undefined the
method.

I'll refrain from talking about BasicObject in ruby1.9 unless asked.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...