From: Eric Hodel Date: 2011-10-04T06:25:02+09:00 Subject: [ruby-core:39896] Re: [Ruby 1.9 - Feature #5372][Open] Promote blank? to a core protocol On Oct 2, 2011, at 2:38 PM, Alex Young wrote: > Eric Hodel wrote in post #1024462: >> On Sep 27, 2011, at 6:52 PM, Alex Young wrote: >> Can you show me a description of the opposite? > > What I mean by "in reverse" is that with the Null Object, we have an > instance which silently does the right thing. We don't have to care that > it's null, we just call methods on it like we would on a non-Null > instance. > > With a #null? or #blank? method, we instead have a way to ask each > instance directly whether it's null, without having to care about its > class. If it quacks like a null, then it's null. I mean, on the C2 wiki or somewhere else on the internet. Can you show other languages that have benefited from a similar implementation? If there is such a document maybe it can help us understand. >>> Because the core API commonly returns nil in error cases.. >> >> Can you show some examples? I don't seem to write nil checks very often >> when using core methods, but maybe I am forgetting. > > Having a quick look over the core docs, there's quite a few in > File::Stat and Process::Status, all the try_convert() methods, > Kernel.caller, Kernel.system, arguably String#slice and Regexp#match > (although I can't see the latter being reasonably alterable), and > Thread#status at least. When does caller return a non-Array? >>> case thingy >>> when Blank >>> # catch-all >>> # other cases >>> end >> >> What about: >> >> case thingy >> # other cases >> else >> # catch-all >> end > > Yep, that's another way to do the same sort of thing, but with a Blank > or Null it's more explicit and more flexible. With a bare > "case...else..." you have to handle both correct nulls and erroneous > values in the "else" clause. With Null, you can leave the "else" clause > purely for handling the error case, where you've somehow got a response > you weren't expecting. I think it's clearer. The problem I see is that adding #empty? to every class is confusing. Should File::Stat#empty? returning true to mean the file is empty? Or should it always return false to say "the file exists" What would Process::Status#empty? mean? Would false mean that the program had exited non-zero or that the program had exited with any status? Kernel#system and Thread#status return true, false, or nil, so combining "non-zero exit" and "command failed" into #empty? isn't clearer to read than 'if system(command) then � else abort "#{command} failed" end' While it might make String#split or Regexp#match and try_convert usage clearer, it adds much confusion otherwise.