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:

it requires keyword arguments no default value; the keywords given array of symbols in 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

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -