Class: RangeExtd::Nowhere
- Inherits:
- BasicObject
- Includes:
- Singleton
- Defined in:
- lib/range_extd/nowhere.rb
Overview
Class RangeExtd::Nowhere
- Authors
-
Masa Sakano
- License
-
MIT
Summary
Singleton Class to host a unique value that behaves like nil except for a couple of methods to distinguish itself from nil and except that it is not regarded as the false value in conditional statements.
Description
The unique value is obtained with instance and is also available as the class constant: NOWHERE
The instance behaves exactly like nil except for the behaviour of the false value in the conditional statement (because unfortunately there is no way in Ruby to make the object behave like false/nil in the conditional statement; see https://stackoverflow.com/a/14449380/3577922) and except for some methods that are defined in BasicObject, such as __id__ (n.b., by contract, object_id of this class’s instance would return the identical id to nil’s), and two custom methods:
-
#nowhere? returns
true -
#class_raw returns this class (n.b., the standard
classmethod returnsNilClass).
and the equality behaviour with eql?, that is,
RangeExtd::Nowhere::NOWHERE.eql?(nil) # => false
whereas
RangeExtd::Nowhere::NOWHERE == nil # => true
This file in itself does not alter NilClass at all. It is highly recommended to do
require "range_extd/nil_class"
to implement these additional features in NilClass so that the behaviours would be comutative. In particular, without requiring it,
nil == RangeExtd::Nowhere::NOWHERE # => false
returns false, which is most likely not convenient. In practice, if you require “range_extd”, the file is also automatically required and so you do not have to worry about it, unless you decide to use this class independently of the main RangeExtd.
Note about the behaviour in conditional statements
The (sole) instance of this class behaves like true like in the conditional statement unlike nil which behaves like the false value. Unfortunately, there is no way in Ruby to make an object behave like false/nil in the conditional statement; see https://stackoverflow.com/a/14449380/3577922. In the conceptual sense, however, the difference should not be a problem. If one checks whether a Range (say, range) is beginless/endless on the basis of its begin/end value, the judgement should be based on the method nil? or its equivalent like
if range.begin.nil?
and not
if !range.begin
because the latter does not distinguish (..a) and (false..false).
Constant Summary collapse
- NOWHERE =
class Nowhere < BasicObject
self.const_get(:Nowhere).instance
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
returns true if other is nil.
-
#class_raw ⇒ Class
returns this class Nowhere.
-
#eql?(other) ⇒ Boolean
returns false if other is the standard nil of NilClass.
-
#hash(*args) ⇒ Integer
The hash value is adjusted, which is not strictly guaranteed to be unique, though in pracrtice it is most likely to be so.
- #method_missing(method, *args, &block) ⇒ Object
-
#nowhere? ⇒ Boolean
returns true.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
128 129 130 |
# File 'lib/range_extd/nowhere.rb', line 128 def method_missing(method, *args, &block) return nil.send method, *args, &block end |
Instance Method Details
#==(other) ⇒ Boolean
returns true if other is nil.
103 104 105 |
# File 'lib/range_extd/nowhere.rb', line 103 def ==(other) other.nil? end |
#class_raw ⇒ Class
returns this class RangeExtd::Nowhere
Note that the standard class method returns NilClass
96 97 98 |
# File 'lib/range_extd/nowhere.rb', line 96 def class_raw ::RangeExtd::Nowhere end |
#eql?(other) ⇒ Boolean
returns false if other is the standard nil of NilClass.
108 109 110 |
# File 'lib/range_extd/nowhere.rb', line 108 def eql?(other) self.equal? other end |
#hash(*args) ⇒ Integer
The hash value is adjusted, which is not strictly guaranteed to be unique, though in pracrtice it is most likely to be so.
Even without this, nil.eql? would return false. However, it is a special case. Without this, the hash value of RangeExtd::NONE would be the same as that of RangeExtd(..nil, true).
124 125 126 |
# File 'lib/range_extd/nowhere.rb', line 124 def hash(*args) nil.send(:hash, *args) - 1 end |
#nowhere? ⇒ Boolean
returns true
87 88 89 |
# File 'lib/range_extd/nowhere.rb', line 87 def nowhere? true end |