Skip to content
This repository has been archived by the owner on Apr 17, 2018. It is now read-only.

Commit

Permalink
Refactored Property option methods
Browse files Browse the repository at this point in the history
* Instead of asking the parent class for an option value when it is
  unknown, copy the values when the descendant inherits from the
  parent class. Also, when an option value changes in a parent
  class copy the value to all the descendants. This has the same effect
  as the previous code, except that it should be more efficient in
  the general case.
* Replace Property.primitive with a method created using accept_options.
  • Loading branch information
dkubb committed Aug 17, 2010
1 parent 54f8ef7 commit c2d9af2
Showing 1 changed file with 33 additions and 49 deletions.
82 changes: 33 additions & 49 deletions lib/dm-core/property.rb
Expand Up @@ -396,17 +396,20 @@ def descendants
end

# @api private
def inherited(subclass)
add_descendant(subclass)
def inherited(descendant)
add_descendant(descendant)

subclass.primitive primitive
subclass.accept_options(*accepted_options)
descendant.primitive primitive
descendant.accept_options(*accepted_options)

# inherit the options from the parent class
options.each { |key, value| descendant.send(key, value) }
end

# @api private
def add_descendant(subclass)
descendants << subclass
superclass.add_descendant(subclass) if superclass.respond_to?(:add_descendant)
def add_descendant(descendant)
descendants << descendant
superclass.add_descendant(descendant) if superclass.respond_to?(:add_descendant)
end

# @api public
Expand All @@ -421,21 +424,24 @@ def accept_options(*args)
# Load Property options
accepted_options.each do |property_option|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def self.#{property_option}(*args) # def unique(*args)
if args.any? # if args.any?
@#{property_option} = args.first # @unique = args.first
elsif instance_variable_defined?(:@#{property_option}) # elsif instance_variable_defined?(:@unique)
@#{property_option} # @unique
elsif superclass.respond_to?(:#{property_option}) # elsif superclass.respond_to?(:unique)
superclass.#{property_option} # superclass.unique
else # else
nil # nil
end # end
end # end
def self.#{property_option}(value = Undefined) # def self.unique(value = Undefined)
return @#{property_option} if value.equal?(Undefined) # return @unique if value.equal?(Undefined)
descendants.each do |descendant| # descendants.each do |descendant|
descendant.#{property_option}(value) # descendant.unique(value)
end # end
@#{property_option} = value # @unique = value
end # end
RUBY
end

descendants.each {|descendant| descendant.accept_options(*args)}
descendants.each { |descendant| descendant.accept_options(*args) }
end

# @api private
def nullable(*args)
# :required is preferable to :allow_nil, but :nullable maps precisely to :allow_nil
warn "#nullable is deprecated, use #required instead (#{caller[0]})"
allow_nil(*args)
end

# Gives all the options set on this type
Expand All @@ -446,36 +452,14 @@ def self.#{property_option}(*args) # def unique(*args)
def options
options = {}
accepted_options.each do |method|
next if !respond_to?(method) || (value = send(method)).nil?
options[method] = value
value = send(method)
options[method] = send(method) unless value.nil?
end
options
end

# Ruby primitive type to use as basis for this type. See
# Property::PRIMITIVES for list of types.
#
# @param primitive [Class, nil]
# The class for the primitive. If nil is passed in, it returns the
# current primitive
#
# @return [Class] if the <primitive> param is nil, return the current primitive.
#
# @api public
def primitive(primitive = nil)
return @primitive if primitive.nil?
@primitive = primitive
end

# @api private
def nullable(value)
# :required is preferable to :allow_nil, but :nullable maps precisely to :allow_nil
warn "#nullable is deprecated, use #required instead (#{caller[0]})"
allow_nil(value)
end
end

accept_options *Property::OPTIONS
accept_options :primitive, *Property::OPTIONS

# A hook to allow types to extend or modify property it's bound to.
# Implementations are not supposed to modify the state of the type class, and
Expand All @@ -489,11 +473,11 @@ def bind
# @return [String] name of field in data-store
#
# @api semipublic
def field(repository_name = nil)
def field(repository_name = Undefined)
self_repository_name = self.repository_name
klass = self.class

if repository_name
unless repository_name.equal?(Undefined)
warn "Passing in +repository_name+ to #{klass}#field is deprecated (#{caller[0]})"

if repository_name != self_repository_name
Expand Down Expand Up @@ -902,10 +886,10 @@ def assert_valid_options(options)
#
# @api private
def determine_visibility
default_accessor = @options[:accessor] || :public
default_accessor = @options.fetch(:accessor, :public)

@reader_visibility = @options[:reader] || default_accessor
@writer_visibility = @options[:writer] || default_accessor
@reader_visibility = @options.fetch(:reader, default_accessor)
@writer_visibility = @options.fetch(:writer, default_accessor)
end
end # class Property
end

0 comments on commit c2d9af2

Please sign in to comment.