Hey guys I am new to Ruby. I have a question: Do methods have to be always inside classes?
-
@greenhunt2003 : You **are** always in some class, even if you don't define one explicitly. You can see this by i.e. running `ruby -e 'puts self.class'`. – user1934428 Jul 21 '20 at 08:21
-
2@user1934428 nitpicking, but: you are always in the context of an object. That object doesn't have to be a class. (`main` is an instance of `Object`, not `Class`) – Stefan Jul 21 '20 at 08:29
-
@Stefan : Absolutely correct! Thanks for pointing it out. The same applies if we explicitly [add a method to an instance of some class](https://stackoverflow.com/questions/1887845/add-method-to-an-instanced-object). – user1934428 Jul 21 '20 at 08:42
-
2@Stefan: More nitpicking: There are *three* different implicit contexts in Ruby. For the purposes of method *lookup* (and a couple of other things such as ivar lookup), you are indeed always in the context of an *object*. But for the purposes of method *definition*, you are always in the context of a *module*. And for the purposes of constant lookup, you are always in the context of … whatever you want to call what constants are looked up in. And then of course, there is local variable lookup, where you are always in the context of a *lexical scope*. – Jörg W Mittag Jul 21 '20 at 10:35
-
@JörgWMittag: It's always a pleasure to read your comments. Have you ever thought of writing a book in general, and a Ruby book in particular? – Eric Duminil Jul 21 '20 at 21:01
2 Answers
Technically they are aways defined inside a class, but this doesn't mean you always need to open a class to define a method.
Here is what might look like a top-level function in other languages:
def foo
puts self
puts self.class
end
If we simply call foo
, we'll get:
main
Object
This actually defined a private instance method in the Object
class. We see that self
in the top-level scope is a special object called main
.
On the other hand, we can try to call this method on other stuff:
'bar'.foo #!> private method `foo' called for "bar":String (NoMethodError)
This errorred out as foo
is private. We can use a special method called send
to invoke private methods:
'bar'.send :foo
Gets us:
bar
String
We can also define methods in the so-called singleton classes. You can think of them as classes with only a single instance. For example:
foo = 'foo'
def foo.bar
puts 'baz'
end
foo.bar # => baz
'quix'.bar # !> undefined method `bar' for "quix":String
'foo'.bar # !> undefined method `bar' for "foo":String
puts (foo.singleton_class.instance_methods - Object.instance_methods).first
# => bar
Here the bar
method was defined on the singleton class of foo
. Note that even another string with the same contents is still a difference instance, hence it doesn't have the bar
method.

- 35,425
- 9
- 72
- 104
-
2A more common example is a _class method_, e.g. `def String.foo` – it's also just an instance method created in the class' singleton class. – Stefan Jul 21 '20 at 08:34
-
@Stefan yep, that's the best example and also it says that there is no true class methods in Ruby as in other languages as it always bound to an object. – Rajagopalan Jul 21 '20 at 09:00
-
https://ruby-doc.org/core-2.7.1/Kernel.html#method-i-puts isn't defined in a class, though. See Jörg's answer. – Eric Duminil Jul 21 '20 at 10:42
Hey guys I am new to Ruby. I have a question: Do methods have to be always inside classes?
No.
Methods have to be always inside modules. (Class are modules, too.)
Example:
module Foo
def bar; end
end
There is no class here.

- 363,080
- 75
- 446
- 653