RCR 303: nil should accept missing methods and return nil

K

Klaus Stein

John Carter said:
A very simple and generic way of improving the reliability of Ruby
programs is to implement the NullObject pattern by allowing nil to
accept all and every method instead of throwing a NoMethodError.
As far as I understand the whole discussion some wish this behaviour to be
able to do things like

obj.meth1().meth2().meth3()

which should not break if meth2 for some cause returns nil.

On the other hand many people claim this will hide errors (I agree here).
It seems there are two kinds of nils: expected and unexpected ones.

So why dont we deal with the expected ones seperately:

==========================================================
class Object
def nil_friendly
self
end
end

class NilClass
def nil_friendly
Blackhole.instance
end
end

class Blackhole
include Singleton
def method_missing( sym, *args)
nil
end
end

## Now this works:

obj.meth1().meth2().nil_friendly.meth3()
==========================================================

So by inserting .nil_friendly (choose a better/shorter name for this) you
_explicitly_ tell that you don't care if nil ist returned.

This will not break any existing code, will not hide errors, but gives
shorter code without explicit ifs.

Comments?

Klaus Stein
 
R

Robert Klemme

Klaus said:
As far as I understand the whole discussion some wish this behaviour
to be able to do things like

obj.meth1().meth2().meth3()

which should not break if meth2 for some cause returns nil.

On the other hand many people claim this will hide errors (I agree
here). It seems there are two kinds of nils: expected and unexpected
ones.

So why dont we deal with the expected ones seperately:

==========================================================
class Object
def nil_friendly
self
end
end

class NilClass
def nil_friendly
Blackhole.instance
end
end

class Blackhole
include Singleton
def method_missing( sym, *args)
nil
end
end

## Now this works:

obj.meth1().meth2().nil_friendly.meth3()
==========================================================

So by inserting .nil_friendly (choose a better/shorter name for this)
you _explicitly_ tell that you don't care if nil ist returned.

This will not break any existing code, will not hide errors, but gives
shorter code without explicit ifs.

Comments?

What about #nil?

robert
 
K

Klaus Stein

Robert Klemme said:
Klaus said:
obj.meth1().meth2().nil_friendly.meth3()
==========================================================

[ ... ]

Comments?

What about #nil?
nil.nil? -> true
nil.nil_friendly.nil? -> false
We _either_ want to use #nil_friendly _or_ test for nil, so I don't think
this gives any problem. If I explicitly use #nil_friendly, I say, that I
don't care about this being nil, so I will not test for nil.

Klaus Stein
 
R

Robert Klemme

Klaus said:
Robert Klemme said:
Klaus said:
obj.meth1().meth2().nil_friendly.meth3()
==========================================================

[ ... ]

Comments?

What about #nil?
nil.nil? -> true
nil.nil_friendly.nil? -> false
We _either_ want to use #nil_friendly _or_ test for nil, so I don't
think this gives any problem. If I explicitly use #nil_friendly, I
say, that I don't care about this being nil, so I will not test for
nil.

I'm not sure I'm following you here. If it's an expected nil (like for
example an explicitely initialized instance variable) shouldn't this then
behave similarly to nil with regard to this test? I imagine there will be
two equally sized camps in favour for each of the two options...

Kind regards

robert
 
K

Klaus Stein

Robert Klemme said:
Klaus said:
Robert Klemme said:
Klaus Stein wrote:

obj.meth1().meth2().nil_friendly.meth3()
==========================================================

[ ... ]

Comments?

What about #nil?
nil.nil? -> true
nil.nil_friendly.nil? -> false
We _either_ want to use #nil_friendly _or_ test for nil, so I don't
think this gives any problem. If I explicitly use #nil_friendly, I
say, that I don't care about this being nil, so I will not test for
nil.

I'm not sure I'm following you here. If it's an expected nil (like for
example an explicitely initialized instance variable) shouldn't this then
behave similarly to nil with regard to this test? I imagine there will be
two equally sized camps in favour for each of the two options...
Well, from my point of view the semantics of #nil_friendly simply is to not
return nil. I expect the object on which #nil_friendly is applied may be
nil, but i don't expect the result of #nil_friendly to be nil, why should I?
obj.nil_friedly is equal to (obj.nil? ? Blackhole.instance : obj)

I don't see why anyone should try something like obj.nil_friedly.nil?,
because I know that this will return false :)

But I am interested if there are other real drawbacks?

Klaus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,161
Latest member
GertrudeMa
Top