A newbie question about main, Object

Hello!

I am trying to understand Ruby's pure OO concept.
As my understanding is limited, my questions might seem silly...:wink:

1. In irb, if I type self, it returns main which is type of Object.

self

=>main

self.class

=>Object

main

NameError: undefined local variable or method `main' for main:Object
        from (irb):28
        from :0

I understand that main is an instance of type Object.
Why can't I access main directly like main.something?
What *actually* is main?
A global instance?

2. I heard that the top-level functions become methods of Object.
Then am I defining a class (Object)?

If I do the following

print "Hello"

what did I do? Am I in the Object class definition part or outside of
Object?
In other words, is the code <print "Hello"> part of Object?
If not, how is it related to main?

Likewise, if I declare a variable on top-level, is it part of Object?
Of course, it's a global variable.
Is a global variable outside of Object class?
If so, it's not OO...?

Well, I hope I expressed my questions well.

Thanks in advance.

kong

Sam Sungshik Kong wrote:

1. In irb, if I type self, it returns main which is type of Object.

self

=>main

self.class

=>Object

main

NameError: undefined local variable or method `main' for main:Object
        from (irb):28
        from :0

I understand that main is an instance of type Object.
Why can't I access main directly like main.something?
What *actually* is main?
A global instance?

That's a good question.

You could do

$main = self

at the top of your code if you wanted to treat the object as a global
instance. But most of the time, I just forget that this object exists.

IMHO, this object exists primarily so that you can write and call
methods in the top-level scope and then easily migrate them inside a
class or module. A trivial example:

路路路

---
def add(x,y)
   x+y
end

p add(1,3)
---

---
module Operations
   def add(x,y)
     x+y
   end
end

include Operations

p Operations.add(1,3)
---

Hello!

I am trying to understand Ruby's pure OO concept.
As my understanding is limited, my questions might seem silly...:wink:

1. In irb, if I type self, it returns main which is type of Object.

self

=>main

self.class

=>Object

main

NameError: undefined local variable or method `main' for main:Object
        from (irb):28
        from :0

I understand that main is an instance of type Object.
Why can't I access main directly like main.something?
What *actually* is main?
A global instance?

As I understand it, "main" is an object of class Object that everything
outside of other class definitions belongs to, but it is not bound to
a variable. The name "main" is simply the string returned by this object's
"to_s" (or "inspect") method..

Tore

路路路

On Tue, 15 Jun 2004 17:26:30 GMT, Sam Sungshik Kong <ssk@chol.nospam.net> wrote:

2. I heard that the top-level functions become methods of Object.
Then am I defining a class (Object)?

If I do the following

print "Hello"

what did I do? Am I in the Object class definition part or outside of
Object?
In other words, is the code <print "Hello"> part of Object?
If not, how is it related to main?

Likewise, if I declare a variable on top-level, is it part of Object?
Of course, it's a global variable.
Is a global variable outside of Object class?
If so, it's not OO...?

Well, I hope I expressed my questions well.

Thanks in advance.

kong

--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/

If you declare a method at top-level, it is a method of Object. For example:

irb(main):001:0> Object.instance_methods.include? 'foo'
=> false
irb(main):002:0> def foo; puts 'hello'; end
=> nil
irb(main):003:0> Object.instance_methods.include? 'foo'
=> true
irb(main):004:0> Object.new.foo
hello
=> nil
irb(main):005:0> self.foo
hello
=> nil

If you declare a variable at top-level, its scope depends on how you declare it. A local variable (e.g. foo = 'foo') should only be scoped within the current block (or, at top-level, within the top level of the script or interactive session). That means that other objects and methods won't be able to access it. Example:

irb(main):001:0> foo = 'foo'
=> "foo"
irb(main):002:0> def hi; puts foo; end
=> nil
irb(main):003:0> hi
NameError: undefined local variable or method `foo' for main:Object
         from (irb):2:in `hi'
         from (irb):3

If you declare it as an instance variable, it becomes an instance variable of that "main" object:

irb(main):004:0> @foo = 'foo'
=> "foo"
irb(main):005:0> p Object.new
#<Object:0x4e6f8>
=> nil
irb(main):007:0> p self.inspect
"#<Object:0x37a08 @foo=\"foo\">"
=> nil

If you declare it as a class variable, it becomes a class variable of Object:

irb(main):008:0> @@foo = 'foo'
=> "foo"
irb(main):012:0> def Object.hi; puts @@foo; end
=> nil
irb(main):013:0> Object.hi
foo
=> nil

Lastly, if you declare it global, it is of course global (any code in any class or module can access it):

irb(main):015:0> module Demo
irb(main):016:1> class Test
irb(main):017:2> def hi
irb(main):018:3> puts $foo
irb(main):019:3> end
irb(main):020:2> end
irb(main):021:1> end
=> nil
irb(main):022:0> Demo::Test.new.hi
foo
=> nil

I hope that helps to explain matters. This is exactly the behavior I would expect from the scoping rules given for Ruby.

Pacem in terris / Mir / Shanti / Salaam / Heiwa
Kevin R. Bullock

路路路

On Jun 15, 2004, at 12:28 PM, Sam Sungshik Kong wrote:

2. I heard that the top-level functions become methods of Object.
Then am I defining a class (Object)?

If I do the following

print "Hello"

what did I do? Am I in the Object class definition part or outside of
Object?
In other words, is the code <print "Hello"> part of Object?
If not, how is it related to main?

Likewise, if I declare a variable on top-level, is it part of Object?
Of course, it's a global variable.
Is a global variable outside of Object class?
If so, it's not OO...?

Joel VanderWerf wrote:

---
module Operations
  def add(x,y)
    x+y
  end
end

include Operations

p Operations.add(1,3)
---

Oops. This code works, but it's a little confusing. Since I included Operations, all I needed to do was

p add(1,3)

If I hadn't included Operations, then

p Operations.add(1,3)

would _not_ work, because add is an instance method, not a module method, of Operations.

Now I've probably only increased the confusion. There are better explanations in the Pick Axe book:

http://www.ruby-doc.org/docs/ProgrammingRuby

IMHO, this object exists primarily so that you can write and call
methods in the top-level scope and then easily migrate them inside a
class or module. A trivial example:

The glossary say, about main

: ((:main:))

    '((|((<self>))|))' at top level.

    Since it can't be without self,
    it is a mere ((<instance|Instance>)) of an ((<Object>)) class,
    only for being there.
    Some ((<singleton methods|Singleton Method>)) are defined
    to operate the Object class.

    Defined ((<singleton method|Singleton Method>)):

     * private
     * public
     * include

Guy Decoux

Excellent explanation, Kevin!

Kevin, what is the right way to think about a global variable?
In pure OO, there's no real global variable, right?
Then, is it against OO?

Thanks.

kong

"Kevin Bullock" <kbullock@ringworld.org> wrote in message
news:A13F8D2C-C149-11D8-BECE-000393BDB320@ringworld.org...

路路路

On Jun 15, 2004, at 12:28 PM, Sam Sungshik Kong wrote:

> 2. I heard that the top-level functions become methods of Object.
> Then am I defining a class (Object)?
>
> If I do the following
>> print "Hello"
> what did I do? Am I in the Object class definition part or outside of
> Object?
> In other words, is the code <print "Hello"> part of Object?
> If not, how is it related to main?
>
> Likewise, if I declare a variable on top-level, is it part of Object?
> Of course, it's a global variable.
> Is a global variable outside of Object class?
> If so, it's not OO...?

If you declare a method at top-level, it is a method of Object. For
example:

irb(main):001:0> Object.instance_methods.include? 'foo'
=> false
irb(main):002:0> def foo; puts 'hello'; end
=> nil
irb(main):003:0> Object.instance_methods.include? 'foo'
=> true
irb(main):004:0> Object.new.foo
hello
=> nil
irb(main):005:0> self.foo
hello
=> nil

If you declare a variable at top-level, its scope depends on how you
declare it. A local variable (e.g. foo = 'foo') should only be scoped
within the current block (or, at top-level, within the top level of the
script or interactive session). That means that other objects and
methods won't be able to access it. Example:

irb(main):001:0> foo = 'foo'
=> "foo"
irb(main):002:0> def hi; puts foo; end
=> nil
irb(main):003:0> hi
NameError: undefined local variable or method `foo' for main:Object
         from (irb):2:in `hi'
         from (irb):3

If you declare it as an instance variable, it becomes an instance
variable of that "main" object:

irb(main):004:0> @foo = 'foo'
=> "foo"
irb(main):005:0> p Object.new
#<Object:0x4e6f8>
=> nil
irb(main):007:0> p self.inspect
"#<Object:0x37a08 @foo=\"foo\">"
=> nil

If you declare it as a class variable, it becomes a class variable of
Object:

irb(main):008:0> @@foo = 'foo'
=> "foo"
irb(main):012:0> def Object.hi; puts @@foo; end
=> nil
irb(main):013:0> Object.hi
foo
=> nil

Lastly, if you declare it global, it is of course global (any code in
any class or module can access it):

irb(main):015:0> module Demo
irb(main):016:1> class Test
irb(main):017:2> def hi
irb(main):018:3> puts $foo
irb(main):019:3> end
irb(main):020:2> end
irb(main):021:1> end
=> nil
irb(main):022:0> Demo::Test.new.hi
foo
=> nil

I hope that helps to explain matters. This is exactly the behavior I
would expect from the scoping rules given for Ruby.

Pacem in terris / Mir / Shanti / Salaam / Heiwa
Kevin R. Bullock

This thread brought up an interesting idea in my mind. If one truly wants to define a top-level method, perhaps you could do this:

irb(main):001:0> class << self
irb(main):002:1> def foo; puts "singleton method of top-level Object instance"; end
irb(main):003:1> end
=> nil
irb(main):004:0> foo
singleton method of top-level Object instance
=> nil
irb(main):005:0> Object.new.foo
NoMethodError: undefined method `foo' for #<Object:0x4c6dc>
         from (irb):5

The usefulness of this depends on what you want a top-level method for. If you want a globally accessible method, the foregoing approach doesn't work:

irb(main):006:0> class Demo
irb(main):007:1> def bar; foo; end
irb(main):008:1> end
=> nil
irb(main):009:0> Demo.new.bar
NameError: undefined local variable or method `foo' for #<Demo:0x216e0>
         from (irb):7:in `bar'
         from (irb):9

But then, globally accessible methods are generally frowned upon in pure OO design. If, on the other hand, you're hacking out a quick script to do something useful, and you want a top-level method that only needs to be accessed at top-level, this works quite well *and* maintains good information hiding practice.

Just some random thoughts I had. Seems like I may have seen this before... is this an established idiom?

Pacem in terris / Mir / Shanti / Salaam / Heiwa
Kevin R. Bullock

路路路

On Jun 16, 2004, at 3:20 AM, ts wrote:

The glossary say, about main

: ((:main:))

    '((|((<self>))|))' at top level.

    Since it can't be without self,
    it is a mere ((<instance|Instance>)) of an ((<Object>)) class,
    only for being there.
    Some ((<singleton methods|Singleton Method>)) are defined
    to operate the Object class.

    Defined ((<singleton method|Singleton Method>)):

     * private
     * public
     * include

Excellent explanation, Kevin!

Glad I could help.

Kevin, what is the right way to think about a global variable?
In pure OO, there's no real global variable, right?
Then, is it against OO?

There's likely to be differing opinions on this matter. I don't think it's necessarily against good object-oriented style to have global variables available in a language. This seems to fit in well with Ruby's approach to interacting very easily with the surrounding system, but still having everything be an object. Ruby preserves information hiding and encapsulation for the general case, as one would expect, and chooses to also allow some variables to be globally accessible. They're seldom used and declared differently, which seems to discourage using them in places they're not meant to be.

There is an argument to be made, though, that allowing global variables does in fact break information hiding, and I have some affinity for that argument as well. But in practice, having globals is useful for covering Perl's problem space with Ruby, even if you never use them when covering Java's problem space.

Pacem in terris / Mir / Shanti / Salaam / Heiwa
Kevin R. Bullock

路路路

On Jun 18, 2004, at 1:43 PM, Sam Sungshik Kong wrote:

Kevin Bullock <kbullock@ringworld.org> writes:

Just some random thoughts I had. Seems like I may have seen this
before... is this an established idiom?

There was a time when toplevel defs were *private* instance methods of
Object. The pickaxe says this anyway. I see nothing in the
Changelogs about any intentional change, so my guess is it's a bug.
Gurus?

Kevin Bullock wrote:

This thread brought up an interesting idea in my mind. If one truly
wants to define a top-level method, perhaps you could do this:

irb(main):001:0> class << self
irb(main):002:1> def foo; puts "singleton method of top-level Object
instance"; end
irb(main):003:1> end
=> nil
irb(main):004:0> foo
singleton method of top-level Object instance
=> nil
irb(main):005:0> Object.new.foo
NoMethodError: undefined method `foo' for #<Object:0x4c6dc>
         from (irb):5

The usefulness of this depends on what you want a top-level method for.
If you want a globally accessible method, the foregoing approach
doesn't work:

irb(main):006:0> class Demo
irb(main):007:1> def bar; foo; end
irb(main):008:1> end
=> nil
irb(main):009:0> Demo.new.bar
NameError: undefined local variable or method `foo' for #<Demo:0x216e0>
         from (irb):7:in `bar'
         from (irb):9

But then, globally accessible methods are generally frowned upon in
pure OO design. If, on the other hand, you're hacking out a quick
script to do something useful, and you want a top-level method that
only needs to be accessed at top-level, this works quite well *and*
maintains good information hiding practice.

[...] is this an established idiom?

Not one that I've seen a lot of.

This script could be useful for self-hypnosis :slight_smile:

def self.roo
  puts "*** (singleton roo) [#{self}] (#{self.class} instance) ***"
  super
end

class Object
  def roo
    puts "*** ( object roo) [#{self}] (#{self.class} instance) ***"
    super
  end
end

module Kernel
  def roo
    puts "*** ( kernel roo) [#{self}] (#{self.class} instance) ***"
  end
end

roo

#=> *** (singleton roo) [main] (Object instance) ***
#=> *** ( object roo) [main] (Object instance) ***
#=> *** ( kernel roo) [main] (Object instance) ***

daz

They still are. This was just an irb thing.

$ cat > foo.rb
def hello
  puts("Hello World")
end

"blah".hello
^D
$ ruby foo.rb
foo.rb:5: private method `hello' called for "blah":String (NoMethodError)

But in irb

irb(main):001:0> def hello
irb(main):002:1> puts("Hello World")
irb(main):003:1> end
=> nil
irb(main):004:0> "blah".hello
Hello World
=> nil

路路路

In article <871xkcdx44.fsf@optushome.com.au>, George Ogata wrote:

Kevin Bullock <kbullock@ringworld.org> writes:

Just some random thoughts I had. Seems like I may have seen this
before... is this an established idiom?

There was a time when toplevel defs were *private* instance methods of
Object. The pickaxe says this anyway. I see nothing in the
Changelogs about any intentional change, so my guess is it's a bug.
Gurus?

>Kevin Bullock <kbullock@ringworld.org> writes:
>
>> Just some random thoughts I had. Seems like I may have seen this
>> before... is this an established idiom?
>
>There was a time when toplevel defs were *private* instance methods of
>Object. The pickaxe says this anyway. I see nothing in the
>Changelogs about any intentional change, so my guess is it's a bug.
>Gurus?

They still are. This was just an irb thing.

$ cat > foo.rb
def hello
  puts("Hello World")
end

"blah".hello
^D
$ ruby foo.rb
foo.rb:5: private method `hello' called for "blah":String (NoMethodError)

But in irb

irb(main):001:0> def hello
irb(main):002:1> puts("Hello World")
irb(main):003:1> end
=> nil
irb(main):004:0> "blah".hello
Hello World
=> nil

路路路

On Sat, 19 Jun 2004 17:28:20 +0900, Tim Sutherland <timsuth@ihug.co.nz> wrote:

In article <871xkcdx44.fsf@optushome.com.au>, George Ogata wrote:

timsuth@ihug.co.nz (Tim Sutherland) writes:

There was a time when toplevel defs were *private* instance methods of
Object. The pickaxe says this anyway. I see nothing in the
Changelogs about any intentional change, so my guess is it's a bug.
Gurus?

They still are. This was just an irb thing.

Oh. irb bug then? :confused: