Comment by pxc

Comment by pxc 9 hours ago

0 replies

> I beg to differ. [...] Why do you not call puts with its objects name?

In the first place, I'd say what you're asking for goes beyond "everything is an object".

But I think your questions can be answered in a way that affirms that "everything is an object" in Ruby anyway.

> Why do you not call puts with its objects name?

Because it belongs to whatever object you're working in already; `puts` is identical to `self.puts`. And yes, you're always working in an object: https://bparanj.gitbooks.io/ruby-basics/content/chapter1.htm...

> What object does the method `puts` belong to?

As indicated above, it belongs to the object `self`. It gets added object via the mixing-in Kernel module into Object. Kernel is itself an instance of class Module: https://docs.ruby-lang.org/en/3.4/Module.html

The `puts` in Kernel delegates to `puts` from IO, which is likewise an instance method belonging to the object you can refer to by the name `$stdout`: https://docs.ruby-lang.org/en/3.4/IO.html

> Ruby has a concept of mixins [and], these are not objects.

Sure they are. Mixins themselves inherit from Module, and Modules are also objects (just like classes are).

Some highlights from Chapter 27 ("Library Reference: The Class Model") of the recent edition of the pickaxe book (emphasis mine):

> The Kernel module is included by class Object, so its methods are available in every Ruby object. One of the reasons for the Kernel module is to allow methods like `puts` and `gets` to be available everywhere and even to look like global commands. Kernel methods allow Ruby to still maintain an "everything is an object semantics".

and regarding mixins:

> The Module class is the class of any module you declare with the `module` keyword. Each module is an instance of class Module.

on Object:

> Object is the parent class of (almost) all classes in Ruby unless a class explicitly inherits from. BasicObject. [...] Object mixes in the Kernel module, making the built-in functions globally accessible.

tl;dr: mixins in Ruby are instances of class Module, and their methods end up bound to instances of class Object. Abstract module methods that don't belong to a concrete instance of some class that mixed in their module belong to the Object that is the module itself (the instance of class Module). (The same kind of thing is how class methods work.)