$meta->superclasses()

[email protected] (Bill Moseley) Sat, 21 Nov 2015 12:07:00 -0800
Newsgroups perl.moose
Message-ID <CAKhN_m7L3izmtyv9J31DVxjG+v186=ncQCiiGiAx3mJwZHXpWQ@mail.gmail.com>
--089e0149d0d8ae88060525128af5
Content-Type: text/plain; charset=UTF-8

I need a bit of help understanding this code in Catalyst used for adding in
Plugins:

            my $meta = Class::MOP::get_metaclass_by_name($class);
            $meta->superclasses($plugin, $meta->superclasses);

This is preventing BUILDARGS from running, and I'm not sure why.  Can
someone provide an explanation?

Thanks!


A Catalyst app extends 'Catalyst', and Catalyst extends Catalyst::Component.
<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits/Catalyst-Runtime.git;a=blob;f=lib/Catalyst.pm;h=7e563cb399229facdf7271c7506b294cb0b35fb3;hb=HEAD#l5>

A Catalyst Component has a config *class* attribute and it also has a
BUILDARGS
<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits/Catalyst-Runtime.git;a=blob;f=lib/Catalyst/Component.pm;h=55f25c0092ec598d69484baabe728a53db37af47;hb=HEAD#l89>
method.  BUILDARGS merges in the component's *class* configuration into the
instance arguments.

In other words, the component's class configuration can populate the
attributes each time the instance is created.

The issue I'm seeing is for (non Moose::Role) plugins the code above is
called and then BUILDARGS is no longer called and thus the config no longer
sets attributes.

The behavior of the app changes depending if loading non-Moose::Role
plugins or not.

So, I have three questions:

First, is is incorrect for Catalyst to use "sub BUILDARGS
<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits/Catalyst-Runtime.git;a=blob;f=lib/Catalyst/Component.pm;h=55f25c0092ec598d69484baabe728a53db37af47;hb=HEAD#l89>"
instead of using the "around" method modifier?


Second, why is Catalyst::Component::BUILDARGS no longer called once

           $meta->superclasses($plugin, $meta->superclasses);

is run?   Is there some other BUILDARGS now overriding?


And third, I have included an example below of a Catalyst app that
demonstrates the behavior above. That app includes a "foo" attribute which
is initialized by the configuration.

Note that the "foo" attribute has "init_args => undef".

The "foo" attribute is initialized when the "MyPlugin" is commented out.

Why is "init_args => undef" not preventing "foo" from being initialized?


Here's a simple script that shows the behavior.

Moose-2.1604
Catalyst-5.90103

$ cat test.pl
package Catalyst::Plugin::MyPlugin;
use Moose;

package Foo;  # A Catalyst app.
use Moose;
extends 'Catalyst';
use Catalyst (
    'MyPlugin',   # <---- comment out to see change
);

has foo => (
    is  => 'ro',
    init_arg => undef,  # How is it that this attribute is ever set?
);

Foo->config(
    foo => { some => 'hash' },
);

Foo->setup;

before dispatch => sub {
    my $self = shift;

    use Data::Dumper;

    *# Show what the value of the attribute is now.*
    *printf "attribute foo is [%s]\n", Dumper $self->foo;*

    die "dead\n";
};


package main;
use strict;
use warnings;
use Catalyst::Test 'Foo';


request '/hello';

Running with the MyPlugin I get:

attribute foo is [$VAR1 = undef;
]


Running w/o the plugin:

attribute foo is [$VAR1 = {
          'some' => 'hash'
        };
]



What's also interesting is if I add this to the the Foo class then the
"foo" attribute is set even when the MyPlugin is included.

before BUILDARGS => sub {};



-- 
Bill Moseley
[email protected]

--089e0149d0d8ae88060525128af5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I need a bit of help understanding this code in Catal=
yst used for adding in Plugins:<br><br></div><div><div>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 my $meta =3D Class::MOP::get_metaclass_by_name($class=
);</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 $meta-&gt;superclass=
es($plugin, $meta-&gt;superclasses);</div></div><div><br></div><div>This is=
 preventing BUILDARGS from running, and I&#39;m not sure why.=C2=A0 Can som=
eone provide an explanation?<br><br>Thanks!</div><div><br></div><div><br></=
div><div>A Catalyst app extends &#39;Catalyst&#39;, and Catalyst <a href=3D=
"http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=3Dcatagits/Catalyst-Runtime=
.git;a=3Dblob;f=3Dlib/Catalyst.pm;h=3D7e563cb399229facdf7271c7506b294cb0b35=
fb3;hb=3DHEAD#l5" target=3D"_blank">extends Catalyst::Component.</a></div><=
div><br></div><div>A Catalyst Component has a config <i>class</i>=C2=A0attr=
ibute=C2=A0and it also has a <a href=3D"http://git.shadowcat.co.uk/gitweb/g=
itweb.cgi?p=3Dcatagits/Catalyst-Runtime.git;a=3Dblob;f=3Dlib/Catalyst/Compo=
nent.pm;h=3D55f25c0092ec598d69484baabe728a53db37af47;hb=3DHEAD#l89" target=
=3D"_blank">BUILDARGS</a> method.=C2=A0 BUILDARGS merges in the component&#=
39;s <i>class</i> configuration into the instance arguments.</div><div><br>=
</div><div>In other words, the component&#39;s class configuration can popu=
late the attributes each time the instance is created.</div><div><br></div>=
<div>The issue I&#39;m seeing is for (non Moose::Role) plugins the code abo=
ve is called and then BUILDARGS is no longer called and thus the config no =
longer sets attributes.</div><div><br></div><div>The behavior of the app ch=
anges depending if loading non-Moose::Role plugins or not.</div><div><br></=
div><div>So, I have three questions:</div><div><br></div><div>First, is is =
incorrect for Catalyst to use &quot;<a href=3D"http://git.shadowcat.co.uk/g=
itweb/gitweb.cgi?p=3Dcatagits/Catalyst-Runtime.git;a=3Dblob;f=3Dlib/Catalys=
t/Component.pm;h=3D55f25c0092ec598d69484baabe728a53db37af47;hb=3DHEAD#l89">=
sub BUILDARGS</a>&quot; instead of using the &quot;around&quot; method modi=
fier?</div><div><br></div><div><br></div><div>Second, why is Catalyst::Comp=
onent::BUILDARGS no longer called once</div><div><br></div><div>=C2=A0=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 $meta-&gt;superclasses($plugin, $meta-&gt;s=
uperclasses);<br></div><div><br></div><div>is run? =C2=A0 Is there some oth=
er BUILDARGS now overriding?</div><div><br></div><div><br></div><div>And th=
ird, I have included an example below of a Catalyst app that demonstrates t=
he behavior above. That app includes a &quot;foo&quot; attribute which is i=
nitialized by the configuration.</div><div><br></div><div>Note that the &qu=
ot;foo&quot; attribute has &quot;init_args =3D&gt; undef&quot;.</div><div><=
br></div><div>The &quot;foo&quot; attribute is initialized when the &quot;M=
yPlugin&quot; is commented out.</div><div><br></div><div>Why is &quot;init_=
args =3D&gt; undef&quot; not preventing &quot;foo&quot; from being initiali=
zed?</div><div><br></div><div><br></div><div>Here&#39;s a simple script tha=
t shows the behavior. =C2=A0</div><div><br></div><div>Moose-2.1604<br></div=
><div>Catalyst-5.90103</div><div><br></div><div><font face=3D"monospace, mo=
nospace">$ cat <a href=3D"http://test.pl">test.pl</a></font></div><div><fon=
t face=3D"monospace, monospace">package Catalyst::Plugin::MyPlugin;<br></fo=
nt></div><div><div><font face=3D"monospace, monospace">use Moose;</font></d=
iv><div><br></div><div><font face=3D"monospace, monospace">package Foo; =C2=
=A0# A Catalyst app.</font></div><div><font face=3D"monospace, monospace">u=
se Moose;</font></div><div><font face=3D"monospace, monospace">extends &#39=
;Catalyst&#39;;</font></div><div><font face=3D"monospace, monospace">use Ca=
talyst (</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0=
 &#39;MyPlugin&#39;, =C2=A0 # &lt;---- comment out to see change</font></di=
v><div><font face=3D"monospace, monospace">);</font></div><div><font face=
=3D"monospace, monospace"><br></font></div><div><font face=3D"monospace, mo=
nospace">has foo =3D&gt; (</font></div><div><font face=3D"monospace, monosp=
ace">=C2=A0 =C2=A0 is =C2=A0=3D&gt; &#39;ro&#39;,</font></div><div><font fa=
ce=3D"monospace, monospace">=C2=A0 =C2=A0 init_arg =3D&gt; undef, =C2=A0# H=
ow is it that this attribute is ever set?</font></div><div><font face=3D"mo=
nospace, monospace">);</font></div><div><font face=3D"monospace, monospace"=
><br></font></div><div><font face=3D"monospace, monospace">Foo-&gt;config(<=
/font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 foo =3D&=
gt; { some =3D&gt; &#39;hash&#39; },</font></div><div><font face=3D"monospa=
ce, monospace">);</font></div><div><font face=3D"monospace, monospace"><br>=
</font></div><div><font face=3D"monospace, monospace">Foo-&gt;setup;</font>=
</div><div><font face=3D"monospace, monospace"><br></font></div><div><font =
face=3D"monospace, monospace">before dispatch =3D&gt; sub {</font></div><di=
v><font face=3D"monospace, monospace">=C2=A0 =C2=A0 my $self =3D shift;</fo=
nt></div><div><font face=3D"monospace, monospace"><br></font></div><div><fo=
nt face=3D"monospace, monospace">=C2=A0 =C2=A0 use Data::Dumper;</font></di=
v><div><font face=3D"monospace, monospace"><br></font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 <b># Show what the value of the att=
ribute is now.</b></font></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 <b>printf &quot;attribute foo is [%s]\n&quot;, Dumper $self-&gt;=
foo;</b><br></font></div><div><font face=3D"monospace, monospace"><br></fon=
t></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 die &quot;de=
ad\n&quot;;</font></div><div><font face=3D"monospace, monospace">};</font><=
/div><div><font face=3D"monospace, monospace"><br></font></div><div><font f=
ace=3D"monospace, monospace"><br></font></div><div><font face=3D"monospace,=
 monospace">package main;</font></div><div><font face=3D"monospace, monospa=
ce">use strict;</font></div><div><font face=3D"monospace, monospace">use wa=
rnings;</font></div><div><font face=3D"monospace, monospace">use Catalyst::=
Test &#39;Foo&#39;;</font></div><div><br></div><div><br></div><div>request =
&#39;/hello&#39;;</div></div><div><br></div><div>Running with the MyPlugin =
I get:</div><div><br></div><blockquote style=3D"margin:0px 0px 0px 40px;bor=
der:none;padding:0px"><div><div>attribute foo is [$VAR1 =3D undef;</div></d=
iv><div><div>]</div></div></blockquote><div><br></div><div>Running w/o the =
plugin:</div><div><br></div><blockquote style=3D"margin:0px 0px 0px 40px;bo=
rder:none;padding:0px"><div><div>attribute foo is [$VAR1 =3D {</div></div><=
div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &#39;some&#39; =3D&gt; &#39;has=
h&#39;</div></div><div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 };</div></div><div>=
<div>]</div></div></blockquote><div><br></div><div><br></div><div>What&#39;=
s also interesting is if I add this to the the Foo class then the &quot;foo=
&quot; attribute is set even when the MyPlugin is included.</div><div><br><=
/div><div>before BUILDARGS =3D&gt; sub {};<br></div><div><br></div><br clea=
r=3D"all"><div><br></div>-- <br><div>Bill Moseley<br><a href=3D"mailto:mose=
[email protected]" target=3D"_blank">[email protected]</a></div>
</div>

--089e0149d0d8ae88060525128af5--