Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are global methods allowed to be defined outside of a class in Ruby?

Tags:

object

ruby

I read this:

Let’s start with a simple Ruby program. We’ll write a method that returns a cheery, personalized greeting.

def say_goodnight(name)
    result = "Goodnight, " + name
    return result
end

My understanding is that a method is a function or subroutine that is defined in a class, which can be associated to a class (class method) or to an object (instance method).

Then, how can that be a method if it was not defined within a class?

like image 712
Patricio Sard Avatar asked Jan 04 '15 16:01

Patricio Sard


People also ask

What's the point of defining methods in Ruby?

Methods are time savers and help the user to reuse the code without retyping the code. Defining & Calling the method: In Ruby, the method defines with the help of def keyword followed by method_name and end with end keyword. A method must be defined before calling and the name of the method should be in lowercase.

How do you define a method within a class using Ruby?

Class Methods are the methods that are defined inside the class, public class methods can be accessed with the help of objects. The method is marked as private by default, when a method is defined outside of the class definition. By default, methods are marked as public which is defined in the class definition.

What is the difference between a class and an instance Ruby?

Classes are a grouping of methods that exist to construct an object by creating a new instance of the class. Instances are the objects created by a class. Class methods are called on the class itself (hence why in the method declaration, it will always state def self.


1 Answers

When you define a function in Ruby at the global scope in this way, it technically becomes a private method of the Object class, which is the base class that everything inherits from in Ruby. Everything in Ruby is an object, so it is indeed true that you have defined a method.

def say_goodnight(name)
    result = "Goodnight, " + name
    return result
end

Object.private_methods.include? :say_goodnight
=> true

Because it is defined as a method with private visibility on Object, it can only be called inside objects of the class on which it's defined or subclasses. So why does it appear to be available globally?

Basically, the Ruby program itself defines an instance of Object called main, which serves as the top-level scope where your method was defined. So if you think of your program as running inside main (which is an Object) its private methods are available for use.

# In irb:
self
=> main
self.class
=> Object
self.private_methods.include? :say_goodnight
=> true

Addendum: This answer which further explains how main is defined and implemented.

Update for Ruby >= 2.3

Noted in the comment thread, later versions of Ruby would define the method Object#say_goodnight in this example with public visibility rather than private. This behavior appears to have changed between Ruby 2.2.x and 2.3.x, but does not affect method exposure.

like image 75
Michael Berkowski Avatar answered Nov 15 '22 08:11

Michael Berkowski