Skip to content

Commit

Permalink
Refactor SQL::Expression attribute handling
Browse files Browse the repository at this point in the history
This makes it more like the rest of Sequel, copying data into
the subclass in inherited instead of calling superclass at
runtime.
  • Loading branch information
jeremyevans committed Aug 16, 2012
1 parent 0aada52 commit f6f5795
Showing 1 changed file with 29 additions and 20 deletions.
49 changes: 29 additions & 20 deletions lib/sequel/sql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,38 @@ module SQL

# Base class for all SQL expression objects.
class Expression
# Expression objects are assumed to be value objects, where their
# attribute values can't change after assignment. In order to make
# it easy to define equality and hash methods, subclass
# instances assume that the only values that affect the results of
# such methods are the values of the object's attributes.
def self.attr_reader(*args)
super
comparison_attrs.concat(args)
end
@comparison_attrs = []

class << self
# All attributes used for equality and hash methods.
attr_reader :comparison_attrs

# Expression objects are assumed to be value objects, where their
# attribute values can't change after assignment. In order to make
# it easy to define equality and hash methods, subclass
# instances assume that the only values that affect the results of
# such methods are the values of the object's attributes.
def attr_reader(*args)
super
comparison_attrs.concat(args)
end

# All attributes used for equality and hash methods.
def self.comparison_attrs
@comparison_attrs ||= self == Expression ? [] : superclass.comparison_attrs.clone
end
# Copy the comparison_attrs into the subclass.
def inherited(subclass)
super
subclass.instance_variable_set(:@comparison_attrs, comparison_attrs.dup)
end

private

# Create a to_s instance method that takes a dataset, and calls
# the method provided on the dataset with args as the argument (self by default).
# Used to DRY up some code.
def self.to_s_method(meth, args=:self) # :nodoc:
class_eval("def to_s(ds) ds.#{meth}(#{args}) end", __FILE__, __LINE__)
class_eval("def to_s_append(ds, sql) ds.#{meth}_append(sql, #{args}) end", __FILE__, __LINE__)
# Create a to_s instance method that takes a dataset, and calls
# the method provided on the dataset with args as the argument (self by default).
# Used to DRY up some code.
def to_s_method(meth, args=:self) # :nodoc:
class_eval("def to_s(ds) ds.#{meth}(#{args}) end", __FILE__, __LINE__)
class_eval("def to_s_append(ds, sql) ds.#{meth}_append(sql, #{args}) end", __FILE__, __LINE__)
end
end
private_class_method :to_s_method

# Alias of <tt>eql?</tt>
def ==(other)
Expand Down

0 comments on commit f6f5795

Please sign in to comment.