If everything is an object in Ruby, to the point that even math operators are methods applied to objects, when I write:
puts "Hello world"
The method is puts, and the parameter is "Hello world", but what is the object?
If everything is an object in Ruby, to the point that even math operators are methods applied to objects, when I write:
puts "Hello world"
The method is puts, and the parameter is "Hello world", but what is the object?
To find a method, you could call :
method(:puts)
#=> #<Method: Object(Kernel)#puts>
So puts
is a method defined in Kernel
, available to every Object.
puts "Hello world"
is actually
self.puts( String.new("Hello world") )
Where self
is the object main
.
So puts "hello world"
is a :
main
Note that if you execute
self.puts( String.new("Hello world") )
you'll get an error :
private method `puts' called for main:Object (NoMethodError)
Because every Kernel method is made available to every Object, but as a private method. You'd need :
self.send(:puts, String.new("Hello world") )
Another way to check would be :
module Kernel
def my_puts(*args)
print "Calling Kernel#my_puts on #{self} with #{args}\n"
print "Now delegating to Kernel#puts on #{self} with #{args} :\n"
puts(*args)
end
end
my_puts "Hello world"
It outputs :
Calling Kernel#my_puts on main with ["Hello world"]
Now delegating to Kernel#puts on main with ["Hello world"] :
Hello world
See? Everything is an object, even though it might not look like it.
In the same vein : 2+3
is actually Integer(2).+( Integer(3) )
.
If everything is an object in Ruby,
That is slightly misleading wording. E.g. syntax is not an object, blocks aren't objects, a conditional expression is not an object.
A better phrasing would be: "every value is an object".
to the point that even math operators are methods applied to objects, when I write:
puts "Hello world"
The method is puts, and the parameter is "Hello world", but what is the object?
There are two objects involved. I suspect what you really meant to ask is "what is the receiver object". (Actually, there are many more objects involved, but let's focus on the receiver and the argument for now.)
A message send always has a receiver object, i.e. the object that you send the message to. If the receiver object is not explicitly written out, it is implicitly assumed to be self
(a pseudo-variable that always evaluates to the "current object"). Now, the question is: what (or "who") is self
here?
This, by the way, is one of the most important questions you should ask yourself when writing Ruby code. Receiverless message sends are to self
, instance variables are looked up in self
. You should always be aware of which object self
is at the point where you are writing your code.
In this particular case, when you write code at what Rubyists call the top-level, self
is a pre-defined object Rubyists call main
. It doesn't actually have a name, and there is no default reference to it, but 'main'
is what it returns when you inspect
it or convert it to a string using to_s
:
to_s
#=> 'main'
inspect
#=> 'main'
The second object you already correctly identified: it is the String
object resulting from the evaluation of the string literal "Hello World"
.
There are, however, more objects involved here. For example, main
is an instance of Object
, so Object
must exist, too. "Hello world"
is an instance of String
, String
must exist. String
and Object
are both classes, i.e. objects which are instances of the Class
class, so Class
must exist. Object
's superclass is BasicObject
. Class
's superclass is Module
. Object
mixes in Kernel
(which is an instance of the Module
class). Kernel#puts
returns nil
, which is an instance of NilClass
. Kernel#puts
is just a helper method that delegates to IO#puts
by calling $stdout.puts
.
So, in addition to main
and "Hello world"
, at least the following objects are also involved: nil
, NilClass
, String
, Class
, Module
, Object
, Kernel
, BasicObject
, IO
, and the IO
object assigned to the global variable $stdout
, representing the standard output stream of your Ruby process.
That's 12 objects which are directly and intimately involved in the execution of your code snippet.
In reality, there are many more objects in even a simple Ruby program:
ruby --disable-gems --disable-did_you_mean -e 'p ObjectSpace.count_objects[:TOTAL]'
On my system, this prints a number around 9780 objects. Now, some of those are the Hash
created by ObjectSpace::count_objects
and the keys and values inside that Hash
(such as the Symbol
object :TOTAL
), and of course the String
created by trying to print out the result. But that's on the order of about ~35 objects, so there's still almost 10000 objects involved in the execution of, well, basically an empty program that does nothing.
blocks aren't objects
Aren't they just disguised Procs? –
Computerize &
no object is created. You can use my pry-objects
gem to validate that. –
Alonsoalonzo "Hello world" is the string object defined as a literal constant given as argument to the puts method
puts "Hello world"
is in fact a simple way to do
puts myFoo
where myFoo must be a valid object... in your case myFoo = "Hello world"
© 2022 - 2024 — McMap. All rights reserved.