From: Yukihiro Matsumoto Date: 2007-12-12T08:41:39+09:00 Subject: Re: redefineable not operator Hi, In message "Re: redefineable not operator" on Wed, 12 Dec 2007 05:14:42 +0900, murphy writes: |> For example, |> |> big_sized_narray.delete_if{|x| x != 0} |> |> to invoke x.!= which creates C coded filter, to avoid evaluating a |> block for each elements in the NArray. |sorry, I don't get this example. I wish I could express more fluently. Why don't you speak Japanese? ;-) OK, I try to explain again, with another example. Suppose we have ActiveRecord class "User" and want to find all users whose name is 'macgyver'. This is how we do: User.select {|m| m.name == 'macgyver'} But if Users table is big, it is inefficient, in both space and time, to fetch all users in an array and to call the block for each user. If we can generate SQL like "SELECT * FROM users WHERE users.`name` = 'macgyver'" from above code, it would be far more efficient. Ambitious takes similar approach, but by parsing Ruby's internal abstract syntax tree, which is fragile between versions. The more reliable approach is passing a stub, which records all method invocation using method_missing, and re-generate call tree. But what if the code contains "!="? User.select {|m| m.name != 'macgyver'} Until 1.8, the != operator cannot be redefined. So we need to use awkward work-around like: User.select {|m| m.name.not_eq('macgyver')} Ugly. This technique (record - re-generate tree - parse) is used to implement some kind of DSL. This is not perfect (e.g. can't capture control structures like if statement), but useful for some cases. matz.