Top-level

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-forum.com/.

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
irb(main):002:0> puts "foo"
foo
=> nil
irb(main):003:0>

Kind regards

  robert

···

On 03.05.2007 20:13, Lucas Holland wrote:
         from :0

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

···

On 5/3/07, Lucas Holland <hollandlucas@gmail.com> wrote:

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Robert Klemme 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 :wink: ). 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

···

On 03.05.2007 20:13, Lucas Holland wrote:

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

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

···

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

Brian Candler 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

···

On Fri, May 04, 2007 at 01:52:21PM +0900, Lucas Holland wrote:

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

Hi --

Brian Candler 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 :slight_smile: 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

···

On 5/4/07, Lucas Holland <hollandlucas@gmail.com> wrote:

> On Fri, May 04, 2007 at 01:52:21PM +0900, Lucas Holland wrote:

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

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.

···

On Fri, May 04, 2007 at 08:50:01PM +0900, Lucas Holland wrote:

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-forum.com/.

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.

···

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

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/