What Is "Main" in Ruby

What is main in Ruby?

Everything in Ruby occurs in the context of some object. The object at the top level is called "main". It's basically an instance of Object with the special property that any methods defined there are added as instance methods of Object (so they're available everywhere).

So we can make a script consisting entirely of:

puts object_id
@a = 'Look, I have instance variables!'
puts @a

and it will print "105640" and "Look, I have instance variables!".

It's not something you generally need to concern yourself with, but it is there.

Is there a main method in Ruby like in C?

@Hauleth's answer is correct: there is no main method or structure in Ruby. I just want to provide a slightly different view here along with some explanation.

When you execute ruby somefile.rb, Ruby executes all of the code in somefile.rb. So if you have a very small project and want it to be self-contained in a single file, there's absolutely nothing wrong with doing something like this:

# somefile.rb

class MyClass
def say_hello
puts "Hello World"
end
end

def another_hello
puts "Hello World (from a method)"
end

c = MyClass.new
c.say_hello
another_hello

It's not that the first two blocks aren't executed, it's just that you don't see the effects until you actually use the corresponding class/method.

The if __FILE__ == $0 bit is just a way to block off code that you only want to run if this file is being run directly from the command line. __FILE__
is the name of the current file, $0 is the command that was executed by the shell (though it's smart enough to drop the ruby), so comparing the two tells you precisely that: is this the file that was executed from the command line? This is sometimes done by coders who want to define a class/module in a file and also provide a command-line utility that uses it. IMHO that's not very good project structure, but just like anything there are use cases where doing it makes perfect sense.

If you want to be able to execute your code directly, you can add a shebang line

#!/usr/bin/env ruby

# rest of somefile.rb

and make it executable with chmod +x somefile.rb (optionally rename it without the .rb extension). This doesn't really change your situation. The if __FILE__ == $0 still works and still probably isn't necessary.

Edit

As @steenslag correctly points out, the top-level scope in Ruby is an Object called main. It has slightly funky behavior, though:

irb
>> self
=> main
>> self.class
=> Object
>> main
NameError: undefined local variable or method `main' for main:Object
from (irb):8

Don't worry about this until you start to dig much deeper into the language. If you do want to learn lots more about this kind of stuff, Metaprogramming Ruby is a great read :)

Where do I write the main function in Ruby?

There is no such thing in Ruby. The interpreter executes code from top to bottom so your main script is implicitly the body of "main". For example, suppose you have two files script_a.rb and script_b.rb. And suppose the contents of script_a.rb is as follows:

require_relative './script_b'

puts 1 + 1

Now if you run ruby script_a.rb what you will get in terms of actual code execution will be as follows: Find script_b.rb, execute the contents of script_b.rb, execute puts 1 + 1.

Should I define a main method in my ruby scripts?

I usually use

if __FILE__ == $0
x = SweetClass.new(ARGV)
x.run # or go, or whatever
end

So yes, you can. It just depends on what you are doing.

`if __name__ == '__main__'` equivalent in Ruby

From the Ruby I've seen out in the wild (granted, not a ton), this is not a standard Ruby design pattern. Modules and scripts are supposed to stay separate, so I wouldn't be surprised if there isn't really a good, clean way of doing this.

EDIT: Found it.

if __FILE__ == $0
foo()
bar()
end

But it's definitely not common.

Instance variables on Ruby main class

@name is an instance variable, @@name would be a class variable.

When you define an instance variable outside any explicit class definition, you implicitly are inside the Object space.

➜  ~  irb
2.1.5 :001 > self.class
=> Object
2.1.5 :002 >

Object is an object, more or less like a custom object. Therefore, when you created

@name = 'learning metaprogramming!'

the instance variable @name exists in the scope of the Object. The method definition happens in the same scope, hence you have accesso the instance variable.

What are the rules for `self` in a top-level method?

All methods defined in the context of main object, will become [private] methods on Object. And since everything is an Object, this method will be available everywhere. And this is also why self is changing based on where you call it from: those are all different objects, but they also all inherit this method.

private_methods.include?(:who_am_i) # => true
foo # => "main"
A.private_methods.include?(:who_am_i) # => true
A.foo # => "A"
A.new.private_methods.include?(:who_am_i) # => true
A.new.foo # => "#<A:0x00007feaad034e00>"

Ruby class methods. Is it getting called on main object?

What is hello being called on?

Whenever there isn't an explicit receiver, the receiver is self. So the call is implicitly:

self.hello

... where self is the class Test, on which you have just defined the self.hello method.

goodbye is not found because it is defined on an instance of class Test, not the class itself, where it's currently called.



Related Topics



Leave a reply



Submit