Is everything object?

On Thu, Apr 28, 2011 at 10:40 PM, Chad P. [email protected] wrote:

I think of operators as methods. Probably the best term for those is
predicate.

Thinking of them as methods is probably a bad idea. It may lead you to
make unwarranted assumptions about things you can do with them.

Can you be more explicit? They are methods, I don’t understand what you
mean.

puts.class
foo(puts)

Those are meaningful, if you are interested in what the method returns
(nil). If you are interested in the method, then don’t invoke it. Since
listing the method’s name is syntactic sugar for invoking it, then how
do
you get the method? Just ask for it method(:puts).extend(Enumerable)

On Thu, Apr 28, 2011 at 10:45 PM, Chad P. [email protected] wrote:

Do you have a real world example of that? Perhaps:

(1, 2, 3).send(:ancestors)

puts.extend Enumerable

That, of course works, puts evalutaes to nil, nil is an object and
therefore
has a singleton class, and therefore can be extended.

puts # => nil
puts.singleton_class.ancestors # => [NilClass, Object, Kernel,
BasicObject]
puts.extend Enumerable
puts.singleton_class.ancestors # => [NilClass, Enumerable, Object,
Kernel,
BasicObject]

On Fri, Apr 29, 2011 at 01:09:25PM +0900, Josh C. wrote:

On Thu, Apr 28, 2011 at 10:40 PM, Chad P. [email protected] wrote:

Thinking of them as methods is probably a bad idea. It may lead you to
make unwarranted assumptions about things you can do with them.

Can you be more explicit? They are methods, I don’t understand what you
mean.

Non-method operators are not methods – by definition.

(nil). If you are interested in the method, then don’t invoke it. Since
listing the method’s name is syntactic sugar for invoking it, then how do
you get the method? Just ask for it method(:puts).extend(Enumerable)

The object is nil, not the method. That’s my point. The puts.class
call
is not a meaningful treatment of puts as an object; it’s just getting
the
Nil class and a blank line output side-effect.

puts.extend Enumerable

That, of course works, puts evalutaes to nil, nil is an object and therefore
has a singleton class, and therefore can be extended.

It doesn’t extend puts; puts is not an object. Trying to think of puts
as an object doesn’t work. It gives surprising results if you actually
expect it to behave as an object in and of itself, thus violating the
“objects and methods” model of Ruby.

On Fri, Apr 29, 2011 at 2:37 PM, Chad P. [email protected] wrote:

That’s because methods are invoked by default, as I already stated. You
need
a line that evaluates to the method, not to nil. Your issue isn’t with
the
objectivity of methods, it is with how you access methods.

this is evaluated

puts # => nil

now we have a reference to it

puts = method :puts # => #<Method: Object(Kernel)#puts>

and look, we can extend it

puts.extend Enumerable # => #<Method: Object(Kernel)#puts>
puts.singleton_class.ancestors # => [Enumerable, Method, Object,
Kernel,
BasicObject]

On Sat, Apr 30, 2011 at 08:01:48AM +0900, Josh C. wrote:

That’s because methods are invoked by default, as I already stated. You need
a line that evaluates to the method, not to nil. Your issue isn’t with the
objectivity of methods, it is with how you access methods.

this is evaluated

puts # => nil

now we have a reference to it

puts = method :puts # => #<Method: Object(Kernel)#puts>

That’s a wrapper – not the method itself.

On 04/28/2011 02:48 AM, amir e. wrote:

Hi
A very important principle in Ruby is that every thing is object.
I read somewhere that there is no primitive operation in Ruby in
traditional form and every operation is class.
Now if every thing is object , then why + , - , * , ^ , ^^ isn’t
class Although they are primitive operation ?

ps : If you test these codes , error happen : +.class -.class *.class

Actually, “everything is an object” is probably a mantra Rubyists should
drop, because people will get confused when they find they can’t call
methods on every piece of Ruby code.

I would say all values in Ruby are objects and all expressions return a
value. But there are (admittedly few) things which are not expressions.

The best thing is to not worry too much about absolutes and just enjoy
exploring.

-Justin

On Sat, Apr 30, 2011 at 02:15:15PM +0900, Chad P. wrote:

now we have a reference to it

puts = method :puts # => #<Method: Object(Kernel)#puts>

That’s a wrapper – not the method itself.

A little elaboration . . .

class String
  def end_upcase
    self.split[-1].upcase       # This Line: Method
  end
end

'foo bar baz'.end_upcase        # String Before Dot: Object Literal
                                # Thing After Dot: Message

The string of characters “end_upcase” in the above isn’t even a method,
per se; it’s a message, sent to the object that is the return value of
the expression preceding it. The return value of an object literal is
the object literal. The return value of a nonliteral object is the
object reference stored under whatever label/variable you use for it, or
the object that is returned by some other form of expression.

So . . . it is not only the case that methods are not objects; it is
also
the case that the thing you probably think of as a method is not a
method. It’s a message, being sent to an object, which in turn probably
has a method defining how it responds to that message.

On Sat, Apr 30, 2011 at 12:55 AM, Chad P. [email protected] wrote:

 end

the object that is returned by some other form of expression.

So . . . it is not only the case that methods are not objects; it is also
the case that the thing you probably think of as a method is not a
method. It’s a message, being sent to an object, which in turn probably
has a method defining how it responds to that message.


Chad P. [ original content licensed OWL: http://owl.apotheon.org ]

I like that distinction, the message is :end_upcase, and the method is
the
code that is invoked. But I still think that considering the method
itself
to be a nonobject has no explanatory value (unless maybe you’re knee
deep in
C), and requires lots of confusing explanations for it to make sense.

IOW, the model is message passing, and when the message is received, it
invokes the method. To get the method then, we must tell the
interpreter,
that we want the method that would be invoked by this message, and it
returns it to us. I think that explains the behaviour quite nicely. Is
there
a model which involves non object methods, which explains something that
this does not, and does not involve completely invisible complications?

I like Chad’s explanation.

I’d like to add that by definition, an object is a state and a behavior.
In the case of a method object, it surely has a behavior, but I would
question its state.

On Sat, Apr 30, 2011 at 04:35:15PM +0900, Josh C. wrote:

I like that distinction, the message is :end_upcase, and the method is
the code that is invoked. But I still think that considering the method
itself to be a nonobject has no explanatory value (unless maybe you’re
knee deep in C), and requires lots of confusing explanations for it to
make sense.

Nah. The method is an expression – often a complex expression composed
of multiple expressions. The object is what receives the message,
contains the method, and executes the method.

IOW, the model is message passing, and when the message is received, it
invokes the method. To get the method then, we must tell the
interpreter, that we want the method that would be invoked by this
message, and it returns it to us. I think that explains the behaviour
quite nicely. Is there a model which involves non object methods, which
explains something that this does not, and does not involve completely
invisible complications?

Within Ruby’s model, you do not tell the interpreter to return the
method, nor to invoke the method. You tell the object to execute the
method. The object checks to see whether it can and, if so, executes
the
method. If not, it lets you know (noisily). If the method exists, the
method is what returns something to you if you sent a message that
corresponds to that method.

The model is explained quite simply:

  1. You send a message to the object.

  2. The object executes a corresponding method.

The method is not something with which you ever interact directly, once
it has been defined. That’s kinda the whole point of this object
model: you create classes to define objects with methods, then
instantiate those objects. You talk to the objects about what you want
them to do, and let them do the heavy lifting.

“Object. Do this for me.”

“Yes, sir!”

Well, you can consider that the state of method includes its name
(message), its source (the textual representation of the code), possibly
its compiled representation (especially in JIT or caching systems), its
comments and its parameters, if any. Arguable, the receiver of a
message is also part of a method’s state, given that (in Smalltalk at
least) one can refer to it using ‘self’.
Having method objects makes powerful debuggers rather easier to
construct, at least if one wants to stay consistently within a message
passing 0-0 paradigm…

regards,
Bill

On Sun, 1 May 2011, Michael S. wrote:

I like Chad’s explanation.

I’d like to add that by definition, an object is a state and a
behavior. In the case of a method object, it surely has a behavior,
but I would question its state.

I’ve dabbled with Smalltalk and Self, and so his explanations of the
way Ruby operates remind me a lot of how the former languages work.

On Sun, May 01, 2011 at 12:48:13AM +0900, Duke N. wrote:

On Sun, 1 May 2011, Michael S. wrote:

I like Chad’s explanation.

I’d like to add that by definition, an object is a state and a
behavior. In the case of a method object, it surely has a behavior,
but I would question its state.

I’ve dabbled with Smalltalk and Self, and so his explanations of the
way Ruby operates remind me a lot of how the former languages work.

Relevant to this, Kent Beck is reputed to have said “I always knew that
one day Smalltalk would replace Java. I just didn’t know it would be
called Ruby.”

That really comes down to implementation details – in Smalltalk, name
(signature), source and parsed representation are indeed internal to the
method. Particularly insofar as you can get those by inspecting the
method objects, which is what the debugger allows us to do.
Questions about what is and what is not ‘in’ an object ultimately come
down to implementation details rather than questions of abstraction. I
find it useful to have a ‘method as object’ abstraction that does
include those things, even if a particular language might not be
implemented so as to support those details of that abstraction. You
appear to differ in perspective/choice of abstraction, and that’s mostly
fine.
But I would challenge the notion that the name of a method, i.e., the
message, i.e., the signature, is not part of the method. What else
could it be?
Now in more general terms, there’s nothing inherent to objects that says
they must be named, or must bind their names as part of their state.
But methods, I think, differ here.

regards,
Bill

On Sun, May 01, 2011 at 01:35:05AM +0900, Bill F. wrote:

Well, you can consider that the state of method includes its name
(message), its source (the textual representation of the code),
possibly its compiled representation (especially in JIT or caching
systems), its comments and its parameters, if any. Arguable, the
receiver of a message is also part of a method’s state, given that (in
Smalltalk at least) one can refer to it using ‘self’. Having method
objects makes powerful debuggers rather easier to construct, at least
if one wants to stay consistently within a message passing 0-0
paradigm…

Not really . . .

The message name, source, and parsed representations of a method are not
internal to the method. Rather, I’d say that the state of an object is
confined to data that you can get out of it via the inspect method
(though I’d entertain arguments that what certain other introspective
methods return might represent an object’s “state” as well). The name
of
a message that corresponds to a given method, the source of the method,
and the parsed representation of it are the runtime’s state. On might
make a case for some of it being the method’s containing object’s state
as well. For instance, the “sort” name could be called a part of the
“[‘foo’,‘bar’,‘baz’]” object, or maybe of the Array class, but not of
the
method (code) an Array object executes when it receives the “sort”
message.

The name of an object is not part of the object’s state, in my view. It
is part of Kernel’s state, perhaps (I’m not 100% on the relationship
between variable declaration and the Kernel object within which
everything executs, as I understand things); definitely part of the
runtime’s state in some way. It is only a label used to refer to the
instantiated object, and not the object itself nor a part of the object.
In fact, these labels (literally) refer to the object, and more than
one can do so at the same time:

> irb --simple-prompt
>> foo = {:foo => 'foo', :bar => 'bar', :baz => 'baz'}
=> {:foo=>"foo", :bar=>"bar", :baz=>"baz"}
>> bar = foo
=> {:foo=>"foo", :bar=>"bar", :baz=>"baz"}
>> baz = {:foo => 'foo', :bar => 'bar', :baz => 'baz'}
=> {:foo=>"foo", :bar=>"bar", :baz=>"baz"}
>> foo == bar
=> true
>> foo == baz
=> true
>> foo.__id__ == bar.__id__
=> true
>> foo.__id__ == baz.__id__
=> false

As you can see, foo, bar, and baz all contain data that evaluates as
equal, but their object IDs are not all the same. The foo and bar
labels
each point to the same object; the baz label points to a different
object
that just happens to contain the same hash data. This is because bar
was
assigned as a label for the same object as foo, but baz was constructed
from scratch, and contains a different object.

My point is that “foo” and “bar” and “baz” are not the objects, are not
parts of the objects, and are not included within the objects’ state by
the intent of the computational model by which we use the code. Rather,
they are labels that refer to the objects. If you subscribe to the
“container” metaphor for variables, you could say that foo contains the
object, but I have long preferred to think of variable names as labels
rather than containers. After all, it would be pretty difficult for two
containers to contain the same object at the same time without one of
them also containing the other from a three-dimensional perspective, but
it’s easy to conceive of slapping more than one label on the same
object.

On Sun, 1 May 2011, Chad P. wrote:

way Ruby operates remind me a lot of how the former languages work.

Relevant to this, Kent Beck is reputed to have said “I always knew that
one day Smalltalk would replace Java. I just didn’t know it would be
called Ruby.”

Too bad the replacement process can’t be speeded a bit.:slight_smile: