Why in top level self assigned some times to Object or main?

Hi,

I write the code below on top level :

module A
def bar
self
end
end

include A # => Object
bar # => main

Now it seems to me that on top level the self changes to either
Object(in case of call to method Module#include) or main( in case of
call to method Object#bar),depending on something. I really would like
to know that something.

Can any one tell me what are the rules written in Ruby for such an auto
switch?

On Sat, Oct 19, 2013 at 7:27 AM, Love U Ruby [email protected]
wrote:

Hi,

bar # => main

The top-level environment is special.

In the top-level methods get defined into Object as private methods by
definition, and the top-level self is a singular object. It is an
instance
of Object with a singleton method #to_s that returns “main”.

That top-level #include is not Modulel#include, it is a special-cased
include called top_include() in MRI that includes into Object by hand
(see
eval.c). Grepping the source code sheds some light:

[email protected]:~/tmp/ruby-1.9.3-p327 $ ag
‘rb_define_singleton_method.*top_self’
eval.c
1150: rb_define_singleton_method(rb_vm_top_self(), “include”,
top_include, -1);

vm.c
2250: rb_define_singleton_method(rb_vm_top_self(), “to_s”,
main_to_s,
0);

vm_method.c
1305: rb_define_singleton_method(rb_vm_top_self(), “public”,
top_public, -1);
1306: rb_define_singleton_method(rb_vm_top_self(), “private”,
top_private, -1);

I don’t think this is officially documented that way anywhere, as a
particular case of Ruby having not much documentation in general. You
should definitely buy Flanagan & Matsumoto to get your ideas ordered,
but
even this book is not exhaustive, and in particular doesn’t mention
include
as a singleton method of the top-level self.

Xavier N. wrote in post #1124893:

On Sat, Oct 19, 2013 at 7:27 AM, Love U Ruby [email protected]
wrote:
I don’t think this is officially documented that way anywhere, as a
particular case of Ruby having not much documentation in general. You
should definitely buy Flanagan & Matsumoto to get your ideas ordered,
but
even this book is not exhaustive, and in particular doesn’t mention
include
as a singleton method of the top-level self.

Okay…

method(:include).owner # => #<Class:#Object:0x96cb250>
singleton_class # => #<Class:#Object:0x96cb250>
def foo;end
singleton_class.private_methods.grep(/foo/)

=> [:foo]

Anything we will be defining on top level is goes to the scope of
singleton_class of "main",as the above code telling. Well,but then why
on the top level call to #include method return the receiver as
Object,instead of the #<Class:#<Object:0x96cb250>> ?

Let me help myself to understand the behavior of top-level.

def foo;end
X=10
Object.const_defined?(:X,false) # => true
Object.private_method_defined?(:foo) # => true

So till now,what I can see is if i defined method,or constants on top
level those will be going to the scope of the class Object.

@x=10
Object.instance_variables # => []
instance_variables # => [:@x]

Now scope has been changed. @x is created in the scope of main,not the
Object class scope.

That means in top level,scope is changed dynamically as per the
situation. Am I right? If I am right,what are the predefined rules of
such dynamic changing of scope on top level.

One more question - I understood that the include is a private method.So
it should be called using implicit self. Who is that implicit self?

You have to stop using the ill-defined concept of “scope”, there is no
scope being switched in between lines. The next time your brain produces
the word “scope” while exploring this stop him, try to identify the
well-defined relevant concepts in this thread.

self in the top-level is “main”, a special instance of Object
bootstrapped
by the virtual machine that has that interface I showed before.

The implementation of the singleton method main#include returns Object
by
definition. Since that method is not Module#include it doesn’t need to
follow its rules. It is a different method altogether and doesn’t return
its receiver. See:

https://github.com/ruby/ruby/blob/trunk/eval.c#L1379

nothing is being magically switched. self is main, main responds to some
methods, plain and easy.

Now, at any given point in the source code Ruby has the concept of “if I
define a constant where am I tossing it”. By definition that is
Module.nesting.last || Object.

Regarding “implicit self”. Method calls may have an explicit receiver:

 user.name

but you know that if the receiver is self, you can obviate it:

 name # same as self.name

The receiver in that line of code is an implicit self. It is self, and
it
is implicit.

Xavier N. wrote in post #1124906:

You have to stop using the ill-defined concept of “scope”, there is no
scope being switched in between lines. The next time your brain produces

https://github.com/ruby/ruby/blob/trunk/eval.c#L1379

so all the top level things as per this c file code. I confused too much
while I was reading the blog -
http://banisterfiend.wordpress.com/2010/11/23/what-is-the-ruby-top-level/
and when I was trying to reasoning the explanation to myself. Still this
top level concept is a bit tricky.

On Sat, Oct 19, 2013 at 12:44 PM, Xavier N. [email protected] wrote:

Now, at any given point in the source code Ruby has the concept of "if I

define a constant where am I tossing it". By definition that is
Module.nesting.last || Object.

Errata: Module.nesting.first || Object.

Xavier N. wrote in post #1124910:

On Sat, Oct 19, 2013 at 12:44 PM, Xavier N. [email protected] wrote:

I was trying to understand self

self # => main
class << self
remove_method :inspect
end

self # => #Object:0x8c4324c

I expected error,but why now self is printed as #<Object:0x8c4324c> ?

On Sat, Oct 19, 2013 at 7:40 PM, Love U Ruby [email protected]
wrote:

Xavier N. wrote in post #1124910:

self # => #Object:0x8c4324c

I expected error,but why now self is printed as #<Object:0x8c4324c> ?

I am going to give you a hint:

http://ruby-doc.org/core-2.0.0/Object.html

With that hint and the explanation of what is the top-level self given
in
this thread… Which is the answer to your question?

On Sat, Oct 19, 2013 at 10:44 AM, Love U Ruby [email protected]
wrote:

Xavier N. wrote in post #1124893:

Okay…

method(:include).owner # => #<Class:#Object:0x96cb250>
singleton_class # => #<Class:#Object:0x96cb250>
def foo;end
singleton_class.private_methods.grep(/foo/)

=> [:foo]

Easier: as I told you #foo becomes a private method of Object.

2.0.0-p247 :005 > Object.private_methods.grep(/foo/)
=> [:foo]
2.0.0-p247 :006 > String.private_methods.grep(/foo/)
=> [:foo]

Well,but then why

on the top level call to #include method return the receiver as
Object,instead of the #<Class:#<Object:0x96cb250>> ?

Because the top-level include method does not return its receiver, it
returns the class the module is included in, which is Object.

On Sun, Oct 20, 2013 at 12:33 PM, Love U Ruby [email protected]
wrote:

Thanks Xavier…

methods again on the top level instance singleton class ?

As far as I know, the main purpose is to provide a top-level environment
that is handy for procedural scripts.

For example, in the top-level environment Kernel#gets (procedural-style)
works because self is an instance of Object.

But since self is not a class or module object, you couldn’t mix-in a
module just like your examples did (procedural-style), you’d need to
reopen
Object. Solution: define a custom include as singleton method of the
top-level object.

That is the idea, but I am not in Ruby core, the actual/whole
motivations
are known by the language designers.

Thanks Xavier…

One more point - I just found some of the methods on the top level
instance meta class is defined. And you told earlier that #include call
is not the same as Module#include… That’s now I understood from the
below code.

singleton_class.private_instance_methods(false)

=> [:public, :private, :include, :using, :define_method]

I wanted to know is there any specific reason to be re-defined such 5
methods again on the top level instance singleton class ?

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs