johnbender.us

recent / categories / archives

Posted
22 August 2009 @ 1pm

Tagged
programming, ruby

RQuery: refactored and simplified

I’ve gone back and knocked off a couple of big todos in rquery. Namely, removing the Symbol capability, and using instances of the new OperationCollector in place of the global class variable + mutex required by the Symbol alterations. Also, as a consequence, I was able to remove the Declarations methods ( .is, .is_not ) previously required for use with overloaded operators like ==.

No More Symbols

Previously there were two DSLs coexisting in the library. One opened up the Symbol class and added the declaration methods.

User.where { :age.is == 12 }

This, in my opinion, was an interesting hack and fun to implement but required both global storage for the results of the executing statements and the pollution of the Symbol class. The library’s better half used a block parameter that represented a collection of the attributes provided by ActiveRecord.

User.where { |user| user.age.is == 12 }

In removing support for the Symbol based syntax, the block based version became much cleaner both externally and internally. Externally there’s no longer a need for the .is and .is_not declarations while the from, between, in and contains methods remain the same.

User.where do |user|
  user.age == 12
  user.name.contains "George"
  user.weight.between 160..180
end

Though, because of Ruby’s restriction on overloading the != operator it now looks like:

User.where do |user|
  user.age.not = 12
end

Simple Internals

The internals have been simplified as well. At a glance, there is now a single class that handles the organization of the calls to the adapter for serialization, OperationCollector. In addition every time the where method is called, a new instance of this class is created so there’s no need to have the mutex to prevent race conditions. Please take a look at the newness for more details.

2 Comments

Posted by
Dag
13 September 2009 @ 10pm

You could have #where take a &block and instance_eval it in the context of the object, and have a syntax like User.where { age == 12 }.


Posted by
John Bender
14 September 2009 @ 5am

@Dag

I think the current syntax is terse enough and allows me to avoid using instance_eval which I make a point of avoiding where possible. Feel free to fork and hack as you please though, it would be cool to see an alternate implementation


Leave a Comment