Sha256: f3d732475c04eb0fe1960b508314614bd81a74dd216e3293cc8e05ca053f309f
Contents?: true
Size: 1.99 KB
Versions: 3
Compression:
Stored size: 1.99 KB
Contents
class AttrExtras::AttrInitialize def initialize(klass, names, block) @klass, @names, @block = klass, names, block end attr_reader :klass, :names private :klass, :names def apply # The define_method block can't call our methods, so we need to make # things available via local variables. names = @names block = @block validate_arity = method(:validate_arity) set_ivar_from_hash = method(:set_ivar_from_hash) klass.send(:define_method, :initialize) do |*values| validate_arity.call(values.length, self.class) names.zip(values).each do |name_or_names, value| if name_or_names.is_a?(Array) hash = value || {} known_keys = name_or_names.map { |name| name.to_s.sub(/!\z/, "").to_sym } unknown_keys = hash.keys - known_keys if unknown_keys.any? raise ArgumentError, "Got unknown keys: #{unknown_keys.inspect}; allowed keys: #{known_keys.inspect}" end name_or_names.each do |name| set_ivar_from_hash.call(self, name, hash) end else name = name_or_names instance_variable_set("@#{name}", value) end end if block instance_eval(&block) end end end private def validate_arity(provided_arity, klass) arity_without_hashes = names.count { |name| not name.is_a?(Array) } arity_with_hashes = names.length unless (arity_without_hashes..arity_with_hashes).include?(provided_arity) arity_range = [ arity_without_hashes, arity_with_hashes ].uniq.join("..") raise ArgumentError, "wrong number of arguments (#{provided_arity} for #{arity_range}) for #{klass.name} initializer" end end def set_ivar_from_hash(instance, name, hash) if name.to_s.end_with?("!") actual_name = name.to_s.chop.to_sym value = hash.fetch(actual_name) else actual_name = name value = hash[actual_name] end instance.instance_variable_set("@#{actual_name}", value) end end
Version data entries
3 entries across 3 versions & 1 rubygems
Version | Path |
---|---|
attr_extras-5.2.0 | lib/attr_extras/attr_initialize.rb |
attr_extras-5.1.0 | lib/attr_extras/attr_initialize.rb |
attr_extras-5.0.0 | lib/attr_extras/attr_initialize.rb |