How does Ruby's nil
manifest in code? For example, in Python you might use None for a default argument when it refers to another argument, but in Ruby you can refer to other arguments in the arg list (see this question). In JS, undefined
pops up even more because you can't specify default arguments at all. Can you give an example of how RubyNone
pops up and how it's dealt with?
I'm not looking for just an example开发者_如何学运维 using nil
. Preferably it would be a real code snippet which had to use nil
for some reason or other.
Ruby's nil and Python's None
are equivalent in the sense that they represent the absence of a value. However, people coming from Python may find some behavior surprising. First, Ruby returns nil
in situations Python raises an exception:
Accessing arrays and hashes:
[1, 2, 3][999] # nil. But [].fetch(0) raises an IndexError
{"a" => 1, "b" => 2}["nonexistent"] # nil. But {}.fetch("nonexistent") raises an IndexError
Instance instance variables:
class MyClass
def hello
@thisdoesnotexist
end
end
MyClass.new.hello #=> nil
The second remarkable fact is that nil
is an object with lots of methods. You can even convert it to an integer, float or string:
nil.to_i # 0
nil.to_f # 0.0 # But Integer(nil) or Float(nil) raise a TypeError.
nil.to_s # ""
One use of nil
you often see in Ruby code is the following:
a ||= 10 # or a = a || 10
This works because once a variable has been seen on the left hand side of an assignment, it implicitly has the value nil.
>> if false
.. x = y
.. z
.. end
=> nil
>> x
=> nil
>> z
NameError: undefined local variable or method `z' for main:Object
Thus when the a || 10
part is evaluated, it evaluates to nil || 10
, which yields 10.
nil
and false
are also the only two values in Ruby that are logically false, so it's customary for methods to return nil
in case of failure. There's a gem called andand
that makes use of exactly this, so instead of something like
@first_name &&= @first_name.trim
you can write
@first_name.andand.trim
This basically translates to trim @first_name
if it has a value other than nil
, otherwise evaluate to nil
. As you can imagine this is particularly useful when chaining methods where one of the intermediaries can potentially return nil
.
Besides that nil
is also returned when you are trying to access non-existing collection elements, e.g. in the case of arrays or hashes. Uninitialized instance variables also have the value nil
.
I'm not overly versed in Python, but from what I've seen nil
and None
serve pretty much the same purpose.
In addition to all explanations about nil, ruby also has 'defined?'.
a = nil
p defined?(a) #=> "local-variable"
p a.nil? #=> true
p defined?(b) #=> nil
My Ruby-fu is very weak, but nil
might be what you are looking for. Here is a quick illustration of using nil
in a function as default argument.
irb(main):003:0> def foo(a = nil)
irb(main):004:1> puts a
irb(main):005:1> end
=> nil
irb(main):006:0> foo(1)
1
=> nil
irb(main):007:0> foo()
nil
=> nil
irb(main):008:0>
They’re also used in place of void
: In a static language the compiler will simply forbid you from using the return value of a void
function, but in a dynamic language every procedure has to return something. So the special value nil
is used.
精彩评论