lib/citeproc/attributes.rb in citeproc-1.0.0.pre3 vs lib/citeproc/attributes.rb in citeproc-1.0.0.pre4

- old
+ new

@@ -1,45 +1,54 @@ module CiteProc - + module Attributes extend Forwardable def self.included(base) base.extend(ClassMethods) end - + def attributes @attributes ||= {} end - + def_delegators :attributes, :length, :empty?, :values_at, :key?, :value? alias size length - + def read_attribute(key) attributes[filter_key(key)] end alias [] read_attribute def write_attribute(key, value) attributes[filter_key(key)] = filter_value(value) end alias []= write_attribute - + + def attribute?(key) + value = read_attribute key + + return false if value.nil? + return false if value.respond_to?(:empty?) && value.empty? + + value.to_s !~ /^(false|no|never)$/i + end + def filter_key(key) key.to_sym end - + def filter_value(value, key = nil) value.respond_to?(:deep_copy) ? value.deep_copy : value.dup rescue value end - + def merge(other) return self if other.nil? - + case when other.is_a?(String) && /^\s*\{/ =~ other other = MultiJson.decode(other, :symbolize_keys => true) when other.respond_to?(:each_pair) # do nothing @@ -53,13 +62,12 @@ attributes[filter_key(key)] = filter_value(value, key) end self end - alias update merge - + def reverse_merge(other) fail "not implemented yet" end def to_hash @@ -70,26 +78,26 @@ def to_citeproc Hash[attributes.map { |k,v| [k.to_s, v.respond_to?(:to_citeproc) ? v.to_citeproc : v.to_s] }] end - + # @return [String] a JSON string representation of the attributes def to_json MultiJson.encode(to_citeproc) end # Don't expose internals to public API private :filter_key, :filter_value - + # initialize_copy should be able to access attributes protected :attributes # Two Attribute-based objects are equal if they are the same object, # or if all their attributes are equal using _#eql?_. - # + # # @param other [Object] the other object # @return [Boolean] whether or not self and passed-in object are equal def eql?(other) case when equal?(other) @@ -98,25 +106,25 @@ false else other.attributes.each_pair do |key, value| return false unless attributes[key].eql?(value) end - + true end end # @return [Fixnum] a hash value based on the object's attributes def hash digest = size attributes.each do |attribute| digest ^= attribute.hash end - + digest end - + module ClassMethods def create(parameters) create!(parameters) rescue @@ -137,44 +145,43 @@ def attr_fields(*arguments) arguments.flatten.each do |field| attr_field(*(field.is_a?(Hash) ? field.to_a.flatten : [field]).map(&:to_s)) end end - + def attr_field(field, default = nil, predicate = false) method_id = field.to_s.downcase.gsub(/[-\s]+/, '_') unless instance_methods.include?(method_id) if default define_method(method_id) do - attributes[field.to_sym] + read_attribute field end else define_method(method_id) do - attributes[field.to_sym] ||= default + attributes[filter_key(field)] ||= default end end end writer_id = [method_id,'='].join unless instance_methods.include?(writer_id) define_method(writer_id) do |value| - attributes[field.to_sym] = value + write_attribute field, value end end - - predicate_id = [method_id, '?'].join + + predicate_id = [method_id, '?'].join if predicate && !instance_methods.include?(predicate_id) define_method(predicate_id) do - v = attributes[field.to_sym] - !(!v || (v.respond_to?(:empty?) && v.empty?) || v.to_s =~ /^(false|no|never)$/i) + attribute?(field) end - + has_predicate = ['has_', predicate_id].join alias_method(has_predicate, predicate_id) unless instance_methods.include?(has_predicate) end end - + end - + end end \ No newline at end of file