Skip to content

Commit

Permalink
Move creating of readers/writers to Attribute class
Browse files Browse the repository at this point in the history
  • Loading branch information
solnic committed Jun 4, 2011
1 parent 3ef2858 commit 71ee457
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 66 deletions.
36 changes: 36 additions & 0 deletions lib/virtus/attributes/attribute.rb
Expand Up @@ -112,6 +112,9 @@ def initialize(name, model, options = {})
default_accessor = @options.fetch(:accessor, DEFAULT_ACCESSOR)
@reader_visibility = @options.fetch(:reader, default_accessor)
@writer_visibility = @options.fetch(:writer, default_accessor)

_create_reader
_create_writer
end

# Returns if the given value's class is an attribute's primitive
Expand Down Expand Up @@ -173,6 +176,39 @@ def set(model, value)
def set!(model, value)
model.instance_variable_set(instance_variable_name, value)
end

# Creates an attribute reader method
#
# @api private
def _create_reader
model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
chainable(:attribute) do
#{reader_visibility}
def #{name}
return #{instance_variable_name} if defined?(#{instance_variable_name})
attribute = self.class.attributes[#{name.inspect}]
#{instance_variable_name} = attribute ? attribute.get(self) : nil
end
end
RUBY

end

# Creates an attribute writer method
#
# @api private
def _create_writer
model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
chainable(:attribute) do
#{writer_visibility}
def #{name}=(value)
self.class.attributes[#{name.inspect}].set(self, value)
end
end
RUBY
end
end # Attribute
end # Attributes
end # Virtus
19 changes: 19 additions & 0 deletions lib/virtus/attributes/boolean.rb
Expand Up @@ -15,6 +15,25 @@ def primitive?(value)
def typecast_to_primitive(value, model = nil)
BOOLEAN_MAP.fetch(value, value)
end

private

# Creates standard and boolean attribute reader methods.
#
# @api private
def _create_reader
super

model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
chainable(:attribute) do
#{reader_visibility}
def #{name}?
#{name}
end
end
RUBY
end
end # Boolean
end # Attributes
end # Virtus
67 changes: 1 addition & 66 deletions lib/virtus/class_methods.rb
Expand Up @@ -42,12 +42,7 @@ def new(attributes = {})
# @api public
def attribute(name, type, options = {})
attribute_klass = Virtus.determine_type(type)
attributes[name] = attribute = attribute_klass.new(name, self, options)

_create_reader(name, attribute)
_create_writer(name, attribute)

attribute
attributes[name] = attribute_klass.new(name, self, options)
end

# Returns all the attributes defined on a Class.
Expand All @@ -62,66 +57,6 @@ def attributes

private

# Creates an attribute reader method
#
# @param [Symbol] name
# the name of an attribute
#
# @param [Virtus::Attributes::Object] attribute
# an attribute instance
#
# @api private
def _create_reader(name, attribute)
instance_variable_name = attribute.instance_variable_name

class_eval <<-RUBY, __FILE__, __LINE__ + 1
chainable(:attributes) do
#{attribute.reader_visibility}
def #{name}
return #{instance_variable_name} if defined?(#{instance_variable_name})
attribute = self.class.attributes[#{name.inspect}]
#{instance_variable_name} = attribute ? attribute.get(self) : nil
end
end
RUBY

boolean_reader_name = "#{name}?"

if attribute.kind_of?(Virtus::Attributes::Boolean)
class_eval <<-RUBY, __FILE__, __LINE__ + 1
chainable(:attributes) do
#{attribute.reader_visibility}
def #{boolean_reader_name}
#{name}
end
end
RUBY
end
end

# Creates an attribute writer method
#
# @param [Symbol] name
# the name of an attribute
#
# @param [Virtus::Attributes::Object] attribute
# an attribute instance
#
# @api private
def _create_writer(name, attribute)
class_eval <<-RUBY, __FILE__, __LINE__ + 1
chainable(:attributes) do
#{attribute.writer_visibility}
def #{name}=(value)
self.class.attributes[#{name.inspect}].set(self, value)
end
end
RUBY
end

# Hooks into const missing process to determine types of attributes.
#
# It is used when an attribute is defined and a global class like String
Expand Down

0 comments on commit 71ee457

Please sign in to comment.