# Cool: nil is a class that can have methods

**URL:** <https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094>\
**Category:** Ruby\
**Created:** [May 20, 2006, 1:55am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094 "2006-05-20T01:55:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 20, 2006, 1:55am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094/1 "2006-05-20T01:55:59Z")

</div>

Excuse a newbee’s enthusiasm, but this is really cool. It makes some  
code that would have had to treat nil specially.

class NilClass  
def each  
yield(self)  
end  
def length  
0  
end  
end

a = nil  
a.each {|a| puts a.class }

Doing it at the Object level is even more handy for the what I was  
playing with.

class Object  
def each  
yield(self)  
end  
def length  
if self == nil then 0 else 1 end  
end  
end

a = nil  
a.each {|a| puts a.length }

So every Object has an each method, which yields itself and has a  
length of 1, so everything can be treated like an array.  
Really neat language.

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 20, 2006, 2:23am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094/2 "2006-05-20T02:23:10Z")

</div>

Hi –

On Sat, 20 May 2006, Rob B. wrote:

> end  
> yield(self)  
> 1, so everything can be treated like an array.  
> Really neat language.

Do be careful, though. Remember that the changes you make to Object  
and NilClass will be in effect for all the library code that you  
include in your application, including the standard library, so if  
anyone else is relying on the fact that some objects respond to “each”  
and others don’t, or that nil is dimensionless, something could go  
wrong.

David

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 20, 2006, 2:54am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094/3 "2006-05-20T02:54:07Z")

</div>

Good point.

Looked sort of handy in the log filter I produced to generate gnuplot  
files. Nil data has meaning in the plot, as distinct from a 0. It is  
also handy to treat a single result in the same way as an array  
result. The collation of the data, from the logs to the plot data  
file, is being driven by an XML description, with embedded ruby  
expressions as XML attributes and text. These XML expressions get  
converted into methods to parse the logs. Having the targets of the  
expressions work seamlessly, despite them being nil, single values or  
arrays, was quite neat.

In the nil case, I wanted it to iterate and be printed as in the same  
way as a non-nil value. In the plot data, a nil prints as ‘-’. I  
hadn’t thought of other code expecting to fail when the value was nil  
or not an array. They probably wont want nil to have a to\_s()  
returning ‘-’ either, not that anything has failed doing this, in  
this instance.

I am modifying it to output multiple rows, for generating Histograms,  
so I will look at doing this in a less dangerous way.

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 20, 2006, 2:44am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094/4 "2006-05-20T02:44:36Z")

</div>

removed\_email\_address@domain.invalid wrote:

> > ```
> > yield(self)
> > 
> > ```
> > 
> > playing with.  
> > a = nil  
> > and others don’t, or that nil is dimensionless, something could go  
> > wrong.
> 
> David

This is what namespace selectors would help fix right? Was there ever a  
decision made about how that would work? Is it in 1.9 now?

-Jeff

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 20, 2006, 4:21am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094/5 "2006-05-20T04:21:37Z")

</div>

Quoting removed\_email\_address@domain.invalid, on Sat, May 20, 2006 at 09:50:49AM +0900:

> In the nil case, I wanted it to iterate and be printed as in the same  
> way as a non-nil value. In the plot data, a nil prints as ‘-’. I  
> hadn’t thought of other code expecting to fail when the value was nil  
> or not an array. They probably wont want nil to have a to\_s()  
> returning ‘-’ either, not that anything has failed doing this, in  
> this instance.

The temptation to change the core classes to work a little more like you  
want is almost overwhelming… at least I have found it so. I guess in  
this case you could do:

def gnuplot\_each(v, &proc)  
if v.respond\_to? :each  
v.each &proc  
else  
yield v  
end  
end

then instead of doing

data.each {…}

you could do

gnuplot\_each(data) {…}

cheers,  
Sam

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 20, 2006, 4:49am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094/6 "2006-05-20T04:49:24Z")

</div>

Quoting removed\_email\_address@domain.invalid, on Sat, May 20, 2006 at 09:20:20AM +0900:

> Do be careful, though. Remember that the changes you make to Object  
> and NilClass will be in effect for all the library code that you  
> include in your application, including the standard library, so if  
> anyone else is relying on the fact that some objects respond to “each”  
> and others don’t, or that nil is dimensionless, something could go  
> wrong.

Whats the current wisdom on how to do this more nicely?

I’ve got a library that added #to\_time to the Date builtin… and its  
conflicting with another much more commonly used library, that has done  
the same thing, but give time in local TZ, not UTC. Oops…

Easy way, is to move my code out into a utility method

module Util  
def to\_time(v)  
case v  
when Time  
v  
when Date  
… cvt v to a Time …  
else  
… ?  
end  
end  
end

but switches on class type are usally a bad thing… in OO code  
generally, and in ruby in particular we are supposed to duck-type, and  
its a real posibility that also DateTime, and perhaps even other date or  
time classes might wander into my code. I’d really like not have this  
kind of switch statement.

What to do?

I could change my method name from Date#to\_time, to  
Date#vpim\_to\_time\_utc, basically namespacing my extension, and adding  
one to Time as well.

I was also considering having some kind of hash:

module Util  
@@cvt\_to\_time\_utc = {  
Time =\> lambda{|t| t },  
Date =\> lambda(|d| Time.utc(d.year, d.mon, d.day)  
}  
def self.cvt\_to\_time\_utc(v)  
@@cvt\_to\_time\_utc[v.class].call(v)  
end  
end

Then 3rd party classes could register some handlers to convert to Time  
in UTC, and I wouldn’t have to modify my case statements.

But… what if they have

class MyTime \< Time  
end

That won’t work… so I could maybe be more clever, search their  
ancestry looking for something that is in my hash… This is starting  
to be a bit of work, and unfotunately similar to what ruby does for  
method dispatch…

Maybe just using name mangling, using my library prefix, is the way to  
go!

Thoughts?

Cheers,  
Sam

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 20, 2006, 5:46am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094/7 "2006-05-20T05:46:59Z")

</div>

Probably total sacrilege, but I was using this to have “nil” as a  
valid value in arithmetic and to treat numbers as if they were  
arrays (in a limited sense). The latter is easy to fix, by storing  
all numbers as 1 element arrays. This solves the iterator on “nil”  
too. All nil values will be in an array, so I just need to iterate on  
the array.

Using “nil” in arithmetic is to differentiate the no data state  
(nil), from having seen a data point, even a 0 value. Probably best  
to subclass Fixnum and build my own objects for arithmetic. Altering  
the numeric classes is definitely a tempting thing though.

I have XML definitions of the source log file and the resulting  
summary I want to get.  
e.g.  
a  
  
…  
  
string  
  
  
string  
  
…  
  
  
…  
  
  
  
int  
  
%d  
  
…

This gets turned into ruby code that parses the log. It uses modified  
column name as variables. The test expression determines if the  
output column is modified, and the value expression is used to set or  
alter the value. If the values start as nil, then adding a value,  
will initialise them. Meeting further values, will result in them  
being added on.

If multiple results are required (e.g. for a histogram), then a value  
expression like  
  
results in the to and from traffic being added to an array result  
called @rslt\_link1, rather than a simple numeric result.

I did this by I adding “each” and “each\_with\_index” to every Object,  
thus allowing numbers and nil values to have an iterator.  
I replaced the Fixnum + with one that would add arrays to numbers,  
giving an array result or Fixnum result, depending on the value being  
added.  
Also the Arrays class was modified to add two arrays, by adding the  
elements at the same array index to each other, not concatenating the  
arrays.  
I then committed the ultimate sin, and added a plus method to nil.

After all these hacks, I can  
add a number to an array, and the first element will get altered.  
add an array to a number, and get an Array with the first element  
altered  
add a number or Array to nil, and get that number or the Array

i.e.

class Object  
def each  
if self != nil then yield(self) end  
end  
def each\_with\_index  
if self != nil then yield(self,0) end  
end  
def length  
if self == nil then 0 else 1 end  
end  
end

class Array  
def +(value)  
value.each\_with\_index { |x,i| self[i] += x }  
self  
end  
end

class Fixnum  
alias oldPlus +  
def +(value)  
if(value.length == 1)  
self.oldPlus(value)  
else  
value.+(self)  
end  
end  
end

class NilClass  
def +(value)  
value  
end  
end

a = [1,3]  
a += [5,2]  
a.each {|b| puts b }  
puts

a = 1  
a += 2  
a.each {|b| puts b }  
puts

a += [5,2]  
a.each {|b| puts b }  
puts

a = nil  
a += 10  
a.each {|b| puts b }  
puts

a = nil  
a += [3,8]  
a.each {|b| puts b }  
puts

a = [“hello”,“I”]  
a += [" world"," repent"]  
a.each {|b| print b, " " }  
puts

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 20, 2006, 9:55am UTC](https://www.ruby-forum.com/t/cool-nil-is-a-class-that-can-have-methods/61094/8 "2006-05-20T09:55:15Z")

</div>

On Sat, May 20, 2006 at 09:42:11AM +0900, Jeff R. wrote:

> This is what namespace selectors would help fix right? Was there ever a  
> decision made about how that would work? Is it in 1.9 now?

It’s not in 1.9 yet. AFAIK this is the last thing we heard about  
selector  
namespaces coming from matz (albeit indirectly):

“He has fixed the SelectorNamespace specification, however, which is  
only in  
his mind now.”

See [http://redhanded.hobix.com/cult/rubyspameeting2006.html](http://redhanded.hobix.com/cult/rubyspameeting2006.html)

As for the specification, [ruby-dev:27417] might give some clues.
