symbols - Pass Ruby object's instance variables to another class's initializer as a map -
i'm using xml-mapping
gem read xml, , want feed mapping objects initializers existing domain classes. given xml like:
<foo bar="baz"><qux>quux</qux></foo>
i object like:
#<foo @bar="baz", @qux="quux">
i want feed domain class like:
class myfoo def initialize(bar:, qux:) # ... etc. end end
(note in myfoo
attributes read-only, , there's validation , transformation goes on in initializer, it's not matter of copying instance variables 1 other.)
i tried transforming instance variables map, thus:
foo.instance_variables.map { |name| [name, foo.instance_variable_get(name)] }.to_h
which produces:
{ :@bar->"baz", :@qux->"quux" }
this almost need myfoo
initializer, not quite -- need is
{ :bar->"baz", :qux->"quux" }
is there way transform instance variable names symbols without @
-sign?
alternatively, there easier way "initialize attributes in object"?
andrey's comment works fine, dislike relying on instance variables directly. suggest adding custom to_h
method foo
class. tie in xml-mapping
following:
class foo # ... def self.__fields__ @__fields__ ||= all_xml_mapping_nodes.map { |r| r.instance_variable_get(:@attrname) } end def to_h self.class.__fields__.each_with_object({}) |field, acc| acc[field] = send(field) end end end
then call myfoo.new(foo.to_h)
.
edit
as extension xml::mapping
:
module xmlmappingextensions def self.included(base) base.extend(classmethods) end module classmethods def __fields__ @__fields__ ||= all_xml_mapping_nodes.map { |r| r.instance_variable_get(:@attrname) } end end def to_h self.class.__fields__.each_with_object({}) |field, acc| acc[field] = send(field) end end end
and either include xmlmappingextensions
in foo
class, or:
module xml::mapping # note: may break xml::mapping if using method # , there more graceful way # tried , seems work fine... def self.included(base) base.send(:include, xmlmappingextensions) end end
after have loaded xml::mapping
, before have loaded foo
class.
Comments
Post a Comment