Jamey Cribbs wrote:

> dblack / wobblini.net wrote:
>
>> Hi --
>>
>> On Sun, 5 Mar 2006, James Edward Gray II wrote:
>>
>>> I'm examining Kirbybase for use it a project and was surprised to 
>>> find this bit of code in it:
>>>
>>> #--------------------------------------------------------------------------- 
>>>
>>> # NilClass
>>> #--------------------------------------------------------------------------- 
>>>
>>> class NilClass
>>>
>>>   def method_missing(method_id, *stuff)
>>>       return nil
>>>   end
>>> end
>>>
>>> This has been a popular discussion lately, but I just don't think 
>>> loading a database library should fundamentally change the 
>>> language.  ActiveRecord doesn't hack NilClass and we seem to do okay 
>>> with that.  Why can't the above example just be coded as:
>>>
>>> select { |r| r.speed and r.speed > 300 }
>>>
>>> or:
>>>
>>> select { |r| r.speed > 300 rescue false }
>>
>>
>>
>> Or, depending on circumstances: r.speed.to_i > 300.  I would ...
>
>
> Thanks very much for the feedback on my overriding 
> NilClass#medthod_missing in KirbyBase.  I don't think the three 
> examples shown above would really be acceptable, because, could you 
> imagine having to do this for every query where there was a chance 
> that  a #method_missing could be thrown?  I think that would get old 
> very fast.
>
> However, the last example does give me an idea.  I'm going to take a 
> look at the KBTable#select method and see if I can wrap the query 
> processing logic in a begin/rescue block.  It may be as simple as what 
> David shows here, have the rescue return false.  The problem I can see 
> is when there is an OR condition in the block, i.e.:
>
> #select { |r| r.speed > 300 or r.range < 900 }
>
> Now, here's a *very* simplified version of KBTable#select, with a 
> proposed adding of a begin/rescue block around the query instead of 
> the current redefining of NilClass#method_missing:
>
> def select(&query_block)
>    valid_matches = []
>    table_records.each do |table_record|
>        begin
>            if query_block(table_record)
>                valid_matches << table_record
>            end
>        rescue NoMethodError
>        end
>    end
> end
>
> Now, lets say we are looping through the table records and we get to a 
> record where :speed is nil and :range is 800.  According to the query 
> block, this record should qualify as a valid match.  But, if I don't 
> override NilClass#method_missing to return fasle, but, instead, try to 
> catch it with a begin/rescue block like I show in the code above, the 
> record will *not* be added to valid matches.  The problem with the 
> code above is that I can't get granular enough.  There is no way to 
> get inside the query block and put a begin/rescue around *each* 
> condition within the block.
> If I could get enough info about the calling method, when I'm inside 
> NilClass#method_missing, then maybe I could conditionally return a 
> false only when it was apparent that the #method_missing exception was 
> raised in KBTable#select.  But, the arguments passed into 
> #method_missing are the symbol of the method, in this case :> and an 
> array containing the arguments passed to the missing method, in this 
> case [300]; not enough info for me to determine if this came from 
> KBTable#select.
>
> I would be very interested in any suggestions, ideas, or feedback on 
> this issue.

Hey, I think I will just respond to myself with a suggestion.  :-)

What has been kicked around when this question has come up before is for 
me to create something like a NULL class and use this to designate a 
null value in the database, instead of using nil.  This would take care 
of having to override NilClass#method_missing.  It would bring up a few 
other problems, namely, what if someone wants to store the string value 
NULL in a field.  But I imagine these could be overcome.

If this is indeed a really big issue (meaning KirbyBase's overriding of 
NilClass#method_missing), then I could get to work on this.  Thoughts?

Jamey