Considering that everything in Ruby is an object and we can open irb and type things like 4.class
and "Text".class
to see from which class an object is, why do if.class
and unless.class
give no return value?
问题:
回答1:
Considering that everything in Ruby is an object
That depends on your definition of "object" and every-"thing". "Object" can mean "entity that can be manipulated by the program" (which I will call object from now on), or "value that is a member of the object system" (which I will call Object
from now on).
In Ruby, everything that can be manipulated by the program (i.e. every object) is also an Object
, i.e. an instance of a class. This is unlike Java, for example, where primitives can be manipulated by the program (i.e. are objects in that sense of the word), but aren't Objects
. In Ruby, this distinction doesn't exist: every object is an Object
and every Object
is also an object.
However, there are things in the language, which cannot be manipulated by the program and which aren't instances of a class, i.e. they are neither object s nor Object
s. These are, for example, methods, variables, syntax, parameter lists, argument lists, keywords.
Note: you can use Ruby's reflection API to give you an object that represents a method or a parameter list, but that object is only a proxy, it is not the real thing.
So, when we say "everything is an object", what we really mean is that "every object is an Object
", i.e. that everything which can be manipulated by the program is also a member of the object system, or in other words, there are no values outside of the object system (unlike primitives in Java). We do not mean that everything that exists in the language can also be manipulated at runtime by the program.
why do
if.class
andunless.class
give no return value
Well, first off, even if if
were an object, those don't do what you think they do: when you say something like foo
in Ruby, it means either "dereference the local variable foo
" or "call the method foo
with self
as the implicit receiver and no argument list". So,
if.class
would either give you the class of the object referenced by the local variable if
or the class of the object returned by the method if
, but never the class of if
itself.
But the if
control flow keyword isn't an object, anyway (neither an object nor an Object
) because keywords and control flow aren't objects in Ruby.
In the book The Ruby Programming Language by Matz and David Flanagan it says on page 2:
every value is an object
Note, it doesn't say every-thing, only every value.
See also the question Is variable is object in ruby?
回答2:
Because they are language keywords and not objects. In general, everything you can assign to a variable is an object.
To be technically correct: keywords such as unless
might have a class that is used by compiler/interpreter (depends on an actual implementation), but you, as a language user, don't have any even remotely practical use for it and so it's not exposed to you.
回答3:
1.9.2-p320 :019 > def meth
1.9.2-p320 :020?> 'meth'
1.9.2-p320 :021?> end
=> nil
1.9.2-p320 :022 >
If you observe the question mark and the indentation, when IRB detects something that needs continuation, it indents.
1.9.2-p320 :022 > if.class
1.9.2-p320 :023?> ...
1.9.2-p320 :028?> end
SyntaxError: (irb):22: syntax error, unexpected '.'
if.class
^
(irb):28: syntax error, unexpected keyword_end, expecting $end
1.9.2-p320 :045 > if.if
1.9.2-p320 :046?> end
SyntaxError: (irb):45: syntax error, unexpected '.'
if.if
^
1.9.2-p320 :060 > str = 'abc'
=> "abc"
1.9.2-p320 :061 > str.
1.9.2-p320 :062 > length
=> 3
1.9.2-p320 :063 >
1.9.2-p320 :083 > if
1.9.2-p320 :084 > str
1.9.2-p320 :085?> puts '>>>'
1.9.2-p320 :086?> end
>>>
=> nil
1.9.2-p320 :087 >
As you can see, IRB does not immediately answer, even if there is an obvious mistake such as sending a message to a reserved word. The ? is the sign that it is waiting for the rest of the statement.