From: Logan Capaldo Date: 2006-03-05T11:13:10+09:00 Subject: Re: Kirbybase Hacks NilClass On Mar 4, 2006, at 8:42 PM, Jamey Cribbs wrote: > Dave Burt wrote: > >> As good a point as that is, I think this is KirbyBase's best >> option. I think the risk of nil.method_missing returning nil >> breaking something is low, as has been argued in the debates on >> this list (Guy Decoux?). If it did, wouldn't we have heard about >> it by now? >> >> It does probably demand a prominent warning in the README. >> > Hey, Dave. Here's what I have smack dab in the middle of the README: > > ---------------------------------------------------------------------- > ----------------------------------- > == Warning > > KirbyBase defines #method_missing for NilClass. This might bite > you in the > butt if you override NilClass.method_missing yourself. > ---------------------------------------------------------------------- > ----------------------------------- > > > The more I think about this, though, could it be as simple as > subclassing NilClass, call it KBNil or whatever? Then I could > override KBNil#method_missing and that wouldn't mess up NilClass. > It would be fairly easy for me to change KirbyBase to return a > KBNil for an empty field value instead of nil. > > Thoughts on this? > > Jamey > This will probably require some deep magic: % irb irb(main):001:0> class KBNil < NilClass irb(main):002:1> end => nil irb(main):003:0> k = KBNil.new NoMethodError: undefined method `new' for KBNil:Class from (irb):3 irb(main):004:0> k = KBNil.allocate TypeError: allocator undefined for KBNil from (irb):4:in `allocate' from (irb):4 Undaunted I tried to trick it some more: irb(main):005:0> class KBNil < NilClass irb(main):006:1> def self.new irb(main):007:2> Class.instance_method(:new).bind(self).call irb(main):008:2> end irb(main):009:1> end => nil irb(main):010:0> k = KBNil.new TypeError: allocator undefined for KBNil from (irb):7:in `new' from (irb):7:in `new' from (irb):10 Ok, I said let's try the same trick with allocate: irb(main):011:0> class KBNil < NilClass irb(main):012:1> def self.allocate irb(main):013:2> Class.instance_method(:allocate).bind (self).call() irb(main):014:2> end irb(main):015:1> end => nil irb(main):016:0> k = KBNil.new TypeError: allocator undefined for KBNil from (irb):7:in `new' from (irb):7:in `new' from (irb):16 And lo, it still did not work. At this point I think it will require a more advanced rubyist than myself. Either that or a C extension. I ran into pretty much the same problem with subclassing FalseClass. nil.dup doesn't really work either. So this comes to an issue of database semantics vs. ruby semantics. Which is probably part of the reason that most DBs do use a custom query language or a variant of SQL.