perl6 - Why isn't my object attribute populated? -
given oversimplified xml file:
<foo>bar</foo>
and code extracts value foo
element:
use xml::rabbit; use data::dump::tree; class runinfo xml::rabbit::node { has $.foo xpath("/foo"); } sub main ( $file! ) { $xml = runinfo.new( file => $file ); dump $xml; put "-----------------------"; put "foo $xml.foo()"; }
you'll see value foo
nil
, though output shows foo bar
:
.runinfo @0 ├ $.foo = nil ├ $.context rw = .xml::document @1 │ ├ $.version = 1.0.str │ ├ $.encoding = nil │ ├ %.doctype = {0} @2 │ ├ $.root = .xml::element @3 │ │ ├ $.name rw = foo.str │ │ ├ @.nodes rw = [1] @4 │ │ │ └ 0 = .xml::text @5 │ │ │ ├ $.text = bar.str │ │ │ └ $.parent rw = .xml::element §3 │ │ ├ %.attribs rw = {0} @7 │ │ ├ $.idattr rw = id.str │ │ └ $.parent rw = .xml::document §1 │ ├ $.filename = example.xml.str │ └ $.parent rw = nil └ $.xpath rw = .xml::xpath @9 ├ $.document = .xml::document §1 └ %.registered-namespaces rw = {0} @11 ----------------------- foo bar
(disclaimer: came across behavior today in code, wrote q & style. other answers welcome.).
by way, here links xml::rabbit , data::dump::tree.
this not result of built-in perl 6 feature, rather xml::rabbit
module does.
that module provides is xpath
trait, , makes sure @ class composition time, attribute has trait applied gets accessor method overridden custom one.
the custom accessor method calculates , sets value attribute first time called, , on subsequent calls returns value that's stored in attribute.
the custom accessor method implemented follows (taken the module's source code parts elided):
method (mu:d:) { $val = $attr.get_value( self ); unless $val.defined { ... $val = ...; ... $attr.set_value( self, $val ); } return $val; }
here, $attr
attribute
object corresponding attribute, , retrieved prior installing method using meta-object protocol (mop).
the data::dump::tree
module, in turn, doesn't use accessor method fetch attributes's value, rather reads directly using mop.
therefore sees attribute's value nil
if has not yet been set because accessor not yet called.
Comments
Post a Comment