metaprogramming - Metaprogrammatically defining Ruby methods that take keyword arguments? -
metaprogramming - Metaprogrammatically defining Ruby methods that take keyword arguments? -
struct
lets me create new class takes arguments , has nice semantics. however, arguments aren't required, , order requires consulting definition:
point = struct.new(:x, :y) point.new(111, 222) #=> <point instance x = 111, y = 222> point.new(111) #=> <point instance x = 111, y = nil>
i'd similar struct, uses keyword arguments instead:
point = stricterstruct.new(:x, :y) point.new(x: 111, y: 222) #=> <point instance x = 111, y = 222> point.new(x: 111) #=> argumenterror
that might this:
module stricterstruct def self.new(*attributes) klass = class.new klass.instance_eval { ... } klass end end
but should go in braces define initialize
method on klass
such that:
attributes
; and the initialize
method assigns them instance variables of same name
i wound using (surprisingly pythonic) **kwargs
strategy, new features in ruby 2.0+:
module stricterstruct def self.new(*attribute_names_as_symbols) c = class.new l = attribute_names_as_symbols c.instance_eval { define_method(:initialize) |**kwargs| unless kwargs.keys.sort == l.sort = kwargs.keys - l missing = l - kwargs.keys raise argumenterror.new <<-message keys not match expected list: -- missing keys: #{missing} -- keys: #{extra} message end kwargs.map |k, v| instance_variable_set "@#{k}", v end end l.each |sym| attr_reader sym end } c end end
ruby metaprogramming
Comments
Post a Comment