PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/lib64/perl5/vendor_perl/Moose/Meta
Viewing File: /usr/lib64/perl5/vendor_perl/Moose/Meta/Role.pm
package Moose::Meta::Role; our $VERSION = '2.2011'; use strict; use warnings; use metaclass; use Scalar::Util 'blessed'; use Moose::Meta::Class; use Moose::Meta::Role::Attribute; use Moose::Meta::Role::Method; use Moose::Meta::Role::Method::Required; use Moose::Meta::Role::Method::Conflicting; use Moose::Meta::Method::Meta; use Moose::Util qw/throw_exception/; use Class::MOP::MiniTrait; use parent 'Class::MOP::Module', 'Class::MOP::Mixin::HasAttributes', 'Class::MOP::Mixin::HasMethods', 'Class::MOP::Mixin::HasOverloads'; Class::MOP::MiniTrait::apply(__PACKAGE__, 'Moose::Meta::Object::Trait'); ## ------------------------------------------------------------------ ## NOTE: ## I normally don't do this, but I am doing ## a whole bunch of meta-programmin' in this ## module, so it just makes sense. For a clearer ## picture of what is going on in the next ## several lines of code, look at the really ## big comment at the end of this file (right ## before the POD). ## - SL ## ------------------------------------------------------------------ my $META = __PACKAGE__->meta; ## ------------------------------------------------------------------ ## attributes ... # NOTE: # since roles are lazy, we hold all the attributes # of the individual role in 'stasis' until which # time when it is applied to a class. This means # keeping a lot of things in hash maps, so we are # using a little of that meta-programmin' magic # here and saving lots of extra typin'. And since # many of these attributes above require similar # functionality to support them, so we again use # the wonders of meta-programmin' to deliver a # very compact solution to this normally verbose # problem. # - SL foreach my $action ( { name => 'excluded_roles_map', attr_reader => 'get_excluded_roles_map' , methods => { add => 'add_excluded_roles', get_keys => 'get_excluded_roles_list', existence => 'excludes_role', } }, { name => 'required_methods', attr_reader => 'get_required_methods_map', methods => { remove => 'remove_required_methods', get_values => 'get_required_method_list', existence => 'requires_method', } }, ) { my $attr_reader = $action->{attr_reader}; my $methods = $action->{methods}; # create the attribute $META->add_attribute($action->{name} => ( reader => $attr_reader, default => sub { {} }, Class::MOP::_definition_context(), )); # create some helper methods $META->add_method($methods->{add} => sub { my ($self, @values) = @_; $self->$attr_reader->{$_} = undef foreach @values; }) if exists $methods->{add}; $META->add_method($methods->{get_keys} => sub { my ($self) = @_; keys %{$self->$attr_reader}; }) if exists $methods->{get_keys}; $META->add_method($methods->{get_values} => sub { my ($self) = @_; values %{$self->$attr_reader}; }) if exists $methods->{get_values}; $META->add_method($methods->{get} => sub { my ($self, $name) = @_; $self->$attr_reader->{$name} }) if exists $methods->{get}; $META->add_method($methods->{existence} => sub { my ($self, $name) = @_; exists $self->$attr_reader->{$name} ? 1 : 0; }) if exists $methods->{existence}; $META->add_method($methods->{remove} => sub { my ($self, @values) = @_; delete $self->$attr_reader->{$_} foreach @values; }) if exists $methods->{remove}; } $META->add_attribute( 'method_metaclass', reader => 'method_metaclass', default => 'Moose::Meta::Role::Method', Class::MOP::_definition_context(), ); $META->add_attribute( 'required_method_metaclass', reader => 'required_method_metaclass', default => 'Moose::Meta::Role::Method::Required', Class::MOP::_definition_context(), ); $META->add_attribute( 'conflicting_method_metaclass', reader => 'conflicting_method_metaclass', default => 'Moose::Meta::Role::Method::Conflicting', Class::MOP::_definition_context(), ); $META->add_attribute( 'application_to_class_class', reader => 'application_to_class_class', default => 'Moose::Meta::Role::Application::ToClass', Class::MOP::_definition_context(), ); $META->add_attribute( 'application_to_role_class', reader => 'application_to_role_class', default => 'Moose::Meta::Role::Application::ToRole', Class::MOP::_definition_context(), ); $META->add_attribute( 'application_to_instance_class', reader => 'application_to_instance_class', default => 'Moose::Meta::Role::Application::ToInstance', Class::MOP::_definition_context(), ); $META->add_attribute( 'applied_attribute_metaclass', reader => 'applied_attribute_metaclass', default => 'Moose::Meta::Attribute', Class::MOP::_definition_context(), ); # More or less copied from Moose::Meta::Class sub initialize { my $class = shift; my @args = @_; unshift @args, 'package' if @args % 2; my %opts = @args; my $package = delete $opts{package}; return Class::MOP::get_metaclass_by_name($package) || $class->SUPER::initialize($package, 'attribute_metaclass' => 'Moose::Meta::Role::Attribute', %opts, ); } sub reinitialize { my $self = shift; my $pkg = shift; my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg); my %existing_classes; if ($meta) { %existing_classes = map { $_ => $meta->$_() } qw( attribute_metaclass method_metaclass wrapped_method_metaclass required_method_metaclass conflicting_method_metaclass application_to_class_class application_to_role_class application_to_instance_class applied_attribute_metaclass ); } my %options = @_; $options{weaken} = Class::MOP::metaclass_is_weak($meta->name) if !exists $options{weaken} && blessed($meta) && $meta->isa('Moose::Meta::Role'); # don't need to remove generated metaobjects here yet, since we don't # yet generate anything in roles. this may change in the future though... # keep an eye on that my $new_meta = $self->SUPER::reinitialize( $pkg, %existing_classes, %options, ); $new_meta->_restore_metaobjects_from($meta) if $meta && $meta->isa('Moose::Meta::Role'); return $new_meta; } sub _restore_metaobjects_from { my $self = shift; my ($old_meta) = @_; $self->_restore_metamethods_from($old_meta); $self->_restore_metaattributes_from($old_meta); for my $role ( @{ $old_meta->get_roles } ) { $self->add_role($role); } } sub add_attribute { my $self = shift; if (blessed $_[0] && ! $_[0]->isa('Moose::Meta::Role::Attribute') ) { my $class = ref $_[0]; throw_exception( CannotAddAsAnAttributeToARole => role_name => $self->name, attribute_class => $class, ); } elsif (!blessed($_[0]) && defined($_[0]) && $_[0] =~ /^\+(.*)/) { throw_exception( AttributeExtensionIsNotSupportedInRoles => attribute_name => $_[0], role_name => $self->name, ); } return $self->SUPER::add_attribute(@_); } sub _attach_attribute { my ( $self, $attribute ) = @_; $attribute->attach_to_role($self); } sub add_required_methods { my $self = shift; for (@_) { my $method = $_; if (!blessed($method)) { $method = $self->required_method_metaclass->new( name => $method, ); } $self->get_required_methods_map->{$method->name} = $method; } } sub add_conflicting_method { my $self = shift; my $method; if (@_ == 1 && blessed($_[0])) { $method = shift; } else { $method = $self->conflicting_method_metaclass->new(@_); } $self->add_required_methods($method); } ## ------------------------------------------------------------------ ## method modifiers # NOTE: # the before/around/after method modifiers are # stored by name, but there can be many methods # then associated with that name. So again we have # lots of similar functionality, so we can do some # meta-programmin' and save some time. # - SL foreach my $modifier_type (qw[ before around after ]) { my $attr_reader = "get_${modifier_type}_method_modifiers_map"; # create the attribute ... $META->add_attribute("${modifier_type}_method_modifiers" => ( reader => $attr_reader, default => sub { {} }, Class::MOP::_definition_context(), )); # and some helper methods ... $META->add_method("get_${modifier_type}_method_modifiers" => sub { my ($self, $method_name) = @_; #return () unless exists $self->$attr_reader->{$method_name}; my $mm = $self->$attr_reader->{$method_name}; $mm ? @$mm : (); }); $META->add_method("has_${modifier_type}_method_modifiers" => sub { my ($self, $method_name) = @_; # NOTE: # for now we assume that if it exists,.. # it has at least one modifier in it (exists $self->$attr_reader->{$method_name}) ? 1 : 0; }); $META->add_method("add_${modifier_type}_method_modifier" => sub { my ($self, $method_name, $method) = @_; $self->$attr_reader->{$method_name} = [] unless exists $self->$attr_reader->{$method_name}; my $modifiers = $self->$attr_reader->{$method_name}; # NOTE: # check to see that we aren't adding the # same code twice. We err in favor of the # first on here, this may not be as expected foreach my $modifier (@{$modifiers}) { return if $modifier == $method; } push @{$modifiers} => $method; }); } ## ------------------------------------------------------------------ ## override method modifiers $META->add_attribute('override_method_modifiers' => ( reader => 'get_override_method_modifiers_map', default => sub { {} }, Class::MOP::_definition_context(), )); # NOTE: # these are a little different because there # can only be one per name, whereas the other # method modifiers can have multiples. # - SL sub add_override_method_modifier { my ($self, $method_name, $method) = @_; (!$self->has_method($method_name)) || throw_exception( CannotOverrideALocalMethod => method_name => $method_name, role_name => $self->name, ); $self->get_override_method_modifiers_map->{$method_name} = $method; } sub has_override_method_modifier { my ($self, $method_name) = @_; # NOTE: # for now we assume that if it exists,.. # it has at least one modifier in it (exists $self->get_override_method_modifiers_map->{$method_name}) ? 1 : 0; } sub get_override_method_modifier { my ($self, $method_name) = @_; $self->get_override_method_modifiers_map->{$method_name}; } ## general list accessor ... sub get_method_modifier_list { my ($self, $modifier_type) = @_; my $accessor = "get_${modifier_type}_method_modifiers_map"; keys %{$self->$accessor}; } sub _meta_method_class { 'Moose::Meta::Method::Meta' } ## ------------------------------------------------------------------ ## subroles $META->add_attribute('roles' => ( reader => 'get_roles', default => sub { [] }, Class::MOP::_definition_context(), )); sub add_role { my ($self, $role) = @_; (blessed($role) && $role->isa('Moose::Meta::Role')) || throw_exception( AddRoleToARoleTakesAMooseMetaRole => role_to_be_added => $role, role_name => $self->name, ); push @{$self->get_roles} => $role; $self->reset_package_cache_flag; } sub calculate_all_roles { my $self = shift; my %seen; grep { !$seen{$_->name}++ } ($self, map { $_->calculate_all_roles } @{ $self->get_roles }); } sub does_role { my ($self, $role) = @_; (defined $role) || throw_exception( RoleNameRequiredForMooseMetaRole => role_name => $self->name ); my $role_name = blessed $role ? $role->name : $role; # if we are it,.. then return true return 1 if $role_name eq $self->name; # otherwise.. check our children foreach my $role (@{$self->get_roles}) { return 1 if $role->does_role($role_name); } return 0; } sub find_method_by_name { (shift)->get_method(@_) } ## ------------------------------------------------------------------ ## role construction ## ------------------------------------------------------------------ sub apply { my ($self, $other, %args) = @_; (blessed($other)) || throw_exception( ApplyTakesABlessedInstance => param => $other, role_name => $self->name, ); my $application_class; if ($other->isa('Moose::Meta::Role')) { $application_class = $self->application_to_role_class; } elsif ($other->isa('Moose::Meta::Class')) { $application_class = $self->application_to_class_class; } else { $application_class = $self->application_to_instance_class; } Moose::Util::_load_user_class($application_class); if ( exists $args{'-excludes'} ) { # I wish we had coercion here :) $args{'-excludes'} = ( ref $args{'-excludes'} eq 'ARRAY' ? $args{'-excludes'} : [ $args{'-excludes'} ] ); } return $application_class->new(%args)->apply($self, $other, \%args); } sub composition_class_roles { } sub combine { my ($class, @role_specs) = @_; require Moose::Meta::Role::Composite; my (@roles, %role_params); while (@role_specs) { my ($role, $params) = @{ splice @role_specs, 0, 1 }; my $requested_role = blessed $role ? $role : Class::MOP::class_of($role); my $actual_role = $requested_role->_role_for_combination($params); push @roles => $actual_role; next unless defined $params; $role_params{$actual_role->name} = $params; } my $c = Moose::Meta::Role::Composite->new(roles => \@roles); return $c->apply_params(\%role_params); } sub _role_for_combination { my ($self, $params) = @_; return $self; } sub create { my $class = shift; my @args = @_; unshift @args, 'package' if @args % 2 == 1; my %options = @args; (ref $options{attributes} eq 'HASH') || throw_exception( CreateTakesHashRefOfAttributes => params => \%options, attribute_class => $class ) if exists $options{attributes}; (ref $options{methods} eq 'HASH') || throw_exception( CreateTakesHashRefOfMethods => params => \%options, attribute_class => $class ) if exists $options{methods}; (ref $options{roles} eq 'ARRAY') || throw_exception( CreateTakesArrayRefOfRoles => params => \%options, attribute_class => $class ) if exists $options{roles}; my $package = delete $options{package}; my $roles = delete $options{roles}; my $attributes = delete $options{attributes}; my $methods = delete $options{methods}; my $meta_name = exists $options{meta_name} ? delete $options{meta_name} : 'meta'; my $meta = $class->SUPER::create($package => %options); $meta->_add_meta_method($meta_name) if defined $meta_name; if (defined $attributes) { foreach my $attribute_name (keys %{$attributes}) { my $attr = $attributes->{$attribute_name}; $meta->add_attribute( $attribute_name => blessed $attr ? $attr : %{$attr} ); } } if (defined $methods) { foreach my $method_name (keys %{$methods}) { $meta->add_method($method_name, $methods->{$method_name}); } } if ($roles) { Moose::Util::apply_all_roles($meta, @$roles); } return $meta; } sub consumers { my $self = shift; my @consumers; for my $meta (Class::MOP::get_all_metaclass_instances) { next if $meta->name eq $self->name; next unless $meta->isa('Moose::Meta::Class') || $meta->isa('Moose::Meta::Role'); push @consumers, $meta->name if $meta->does_role($self->name); } return @consumers; } # XXX: something more intelligent here? sub _anon_package_prefix { 'Moose::Meta::Role::__ANON__::SERIAL::' } sub create_anon_role { shift->create_anon(@_) } sub is_anon_role { shift->is_anon(@_) } sub _anon_cache_key { my $class = shift; my %options = @_; # XXX fix this duplication (see MMC::_anon_cache_key my $roles = Data::OptList::mkopt(($options{roles} || []), { moniker => 'role', val_test => sub { ref($_[0]) eq 'HASH' }, }); my @role_keys; for my $role_spec (@$roles) { my ($role, $params) = @$role_spec; $params = { %$params }; my $key = blessed($role) ? $role->name : $role; if ($params && %$params) { my $alias = delete $params->{'-alias'} || delete $params->{'alias'} || {}; my $excludes = delete $params->{'-excludes'} || delete $params->{'excludes'} || []; $excludes = [$excludes] unless ref($excludes) eq 'ARRAY'; if (%$params) { warn "Roles with parameters cannot be cached. Consider " . "applying the parameters before calling " . "create_anon_class, or using 'weaken => 0' instead"; return; } my $alias_key = join('%', map { $_ => $alias->{$_} } sort keys %$alias ); my $excludes_key = join('%', sort @$excludes ); $key .= '<' . join('+', 'a', $alias_key, 'e', $excludes_key) . '>'; } push @role_keys, $key; } # Makes something like Role|Role::1 return join('|', sort @role_keys); } ##################################################################### ## NOTE: ## This is Moose::Meta::Role as defined by Moose (plus the use of ## MooseX::AttributeHelpers module). It is here as a reference to ## make it easier to see what is happening above with all the meta ## programming. - SL ##################################################################### # # has 'roles' => ( # metaclass => 'Array', # reader => 'get_roles', # isa => 'ArrayRef[Moose::Meta::Role]', # default => sub { [] }, # provides => { # 'push' => 'add_role', # } # ); # # has 'excluded_roles_map' => ( # metaclass => 'Hash', # reader => 'get_excluded_roles_map', # isa => 'HashRef[Str]', # provides => { # # Not exactly set, cause it sets multiple # 'set' => 'add_excluded_roles', # 'keys' => 'get_excluded_roles_list', # 'exists' => 'excludes_role', # } # ); # # has 'required_methods' => ( # metaclass => 'Hash', # reader => 'get_required_methods_map', # isa => 'HashRef[Moose::Meta::Role::Method::Required]', # provides => { # # not exactly set, or delete since it works for multiple # 'set' => 'add_required_methods', # 'delete' => 'remove_required_methods', # 'keys' => 'get_required_method_list', # 'exists' => 'requires_method', # } # ); # # # the before, around and after modifiers are # # HASH keyed by method-name, with ARRAY of # # CODE refs to apply in that order # # has 'before_method_modifiers' => ( # metaclass => 'Hash', # reader => 'get_before_method_modifiers_map', # isa => 'HashRef[ArrayRef[CodeRef]]', # provides => { # 'keys' => 'get_before_method_modifiers', # 'exists' => 'has_before_method_modifiers', # # This actually makes sure there is an # # ARRAY at the given key, and pushed onto # # it. It also checks for duplicates as well # # 'add' => 'add_before_method_modifier' # } # ); # # has 'after_method_modifiers' => ( # metaclass => 'Hash', # reader =>'get_after_method_modifiers_map', # isa => 'HashRef[ArrayRef[CodeRef]]', # provides => { # 'keys' => 'get_after_method_modifiers', # 'exists' => 'has_after_method_modifiers', # # This actually makes sure there is an # # ARRAY at the given key, and pushed onto # # it. It also checks for duplicates as well # # 'add' => 'add_after_method_modifier' # } # ); # # has 'around_method_modifiers' => ( # metaclass => 'Hash', # reader =>'get_around_method_modifiers_map', # isa => 'HashRef[ArrayRef[CodeRef]]', # provides => { # 'keys' => 'get_around_method_modifiers', # 'exists' => 'has_around_method_modifiers', # # This actually makes sure there is an # # ARRAY at the given key, and pushed onto # # it. It also checks for duplicates as well # # 'add' => 'add_around_method_modifier' # } # ); # # # override is similar to the other modifiers # # except that it is not an ARRAY of code refs # # but instead just a single name->code mapping # # has 'override_method_modifiers' => ( # metaclass => 'Hash', # reader =>'get_override_method_modifiers_map', # isa => 'HashRef[CodeRef]', # provides => { # 'keys' => 'get_override_method_modifier', # 'exists' => 'has_override_method_modifier', # 'add' => 'add_override_method_modifier', # checks for local method .. # } # ); # ##################################################################### 1; # ABSTRACT: The Moose Role metaclass __END__ =pod =encoding UTF-8 =head1 NAME Moose::Meta::Role - The Moose Role metaclass =head1 VERSION version 2.2011 =head1 DESCRIPTION This class is a subclass of L<Class::MOP::Module> that provides additional Moose-specific functionality. Its API looks a lot like L<Moose::Meta::Class>, but internally it implements many things differently. This may change in the future. =head1 INHERITANCE C<Moose::Meta::Role> is a subclass of L<Class::MOP::Module>. =head1 METHODS =head2 Construction =head3 Moose::Meta::Role->initialize($role_name) This method creates a new role object with the provided name. =head3 Moose::Meta::Role->combine( [ $role => { ... } ], [ $role ], ... ) This method accepts a list of array references. Each array reference should contain a role name or L<Moose::Meta::Role> object as its first element. The second element is an optional hash reference. The hash reference can contain C<-excludes> and C<-alias> keys to control how methods are composed from the role. The return value is a new L<Moose::Meta::Role::Composite> that represents the combined roles. =head3 $metarole->composition_class_roles When combining multiple roles using C<combine>, this method is used to obtain a list of role names to be applied to the L<Moose::Meta::Role::Composite> instance returned by C<combine>. The default implementation returns an empty list. Extensions that need to hook into role combination may wrap this method to return additional role names. =head3 Moose::Meta::Role->create($name, %options) This method is identical to the L<Moose::Meta::Class> C<create> method. =head3 Moose::Meta::Role->create_anon_role This method is identical to the L<Moose::Meta::Class> C<create_anon_class> method. =head3 $metarole->is_anon_role Returns true if the role is an anonymous role. =head3 $metarole->consumers Returns a list of names of classes and roles which consume this role. =head2 Role application =head3 $metarole->apply( $thing, @options ) This method applies a role to the given C<$thing>. That can be another L<Moose::Meta::Role>, object, a L<Moose::Meta::Class> object, or a (non-meta) object instance. The options are passed directly to the constructor for the appropriate L<Moose::Meta::Role::Application> subclass. Note that this will apply the role even if the C<$thing> in question already C<does> this role. L<Moose::Util/does_role> is a convenient wrapper for finding out if role application is necessary. =head2 Roles and other roles =head3 $metarole->get_roles This returns an array reference of roles which this role does. This list may include duplicates. =head3 $metarole->calculate_all_roles This returns a I<unique> list of all roles that this role does, and all the roles that its roles do. =head3 $metarole->does_role($role) Given a role I<name> or L<Moose::Meta::Role> object, returns true if this role does the given role. =head3 $metarole->add_role($role) Given a L<Moose::Meta::Role> object, this adds the role to the list of roles that the role does. =head3 $metarole->get_excluded_roles_list Returns a list of role names which this role excludes. =head3 $metarole->excludes_role($role_name) Given a role I<name>, returns true if this role excludes the named role. =head3 $metarole->add_excluded_roles(@role_names) Given one or more role names, adds those roles to the list of excluded roles. =head2 Methods The methods for dealing with a role's methods are all identical in API and behavior to the same methods in L<Class::MOP::Class>. =head3 $metarole->method_metaclass Returns the method metaclass name for the role. This defaults to L<Moose::Meta::Role::Method>. =head3 $metarole->get_method($name) =head3 $metarole->has_method($name) =head3 $metarole->add_method( $name, $body ) =head3 $metarole->get_method_list =head3 $metarole->find_method_by_name($name) These methods are all identical to the methods of the same name in L<Class::MOP::Package> =head2 Attributes As with methods, the methods for dealing with a role's attribute are all identical in API and behavior to the same methods in L<Class::MOP::Class>. However, attributes stored in this class are I<not> stored as objects. Rather, the attribute definition is stored as a hash reference. When a role is composed into a class, this hash reference is passed directly to the metaclass's C<add_attribute> method. This is quite likely to change in the future. =head3 $metarole->get_attribute($attribute_name) =head3 $metarole->has_attribute($attribute_name) =head3 $metarole->get_attribute_list =head3 $metarole->add_attribute($name, %options) =head3 $metarole->remove_attribute($attribute_name) =head2 Overload introspection and creation The methods for dealing with a role's overloads are all identical in API and behavior to the same methods in L<Class::MOP::Class>. =head3 $metarole->is_overloaded =head3 $metarole->get_overloaded_operator($op) =head3 $metarole->has_overloaded_operator($op) =head3 $metarole->get_overload_list =head3 $metarole->get_all_overloaded_operators =head3 $metarole->add_overloaded_operator($op, $impl) =head3 $metarole->remove_overloaded_operator($op) =head2 Required methods =head3 $metarole->get_required_method_list Returns the list of methods required by the role. =head3 $metarole->requires_method($name) Returns true if the role requires the named method. =head3 $metarole->add_required_methods(@names) Adds the named methods to the role's list of required methods. =head3 $metarole->remove_required_methods(@names) Removes the named methods from the role's list of required methods. =head3 $metarole->add_conflicting_method(%params) Instantiate the parameters as a L<Moose::Meta::Role::Method::Conflicting> object, then add it to the required method list. =head2 Method modifiers These methods act like their counterparts in L<Class::MOP::Class> and L<Moose::Meta::Class>. However, method modifiers are simply stored internally, and are not applied until the role itself is applied to a class or object. =head3 $metarole->add_after_method_modifier($method_name, $method) =head3 $metarole->add_around_method_modifier($method_name, $method) =head3 $metarole->add_before_method_modifier($method_name, $method) =head3 $metarole->add_override_method_modifier($method_name, $method) These methods all add an appropriate modifier to the internal list of modifiers. =head3 $metarole->has_after_method_modifiers =head3 $metarole->has_around_method_modifiers =head3 $metarole->has_before_method_modifiers =head3 $metarole->has_override_method_modifier Return true if the role has any modifiers of the given type. =head3 $metarole->get_after_method_modifiers($method_name) =head3 $metarole->get_around_method_modifiers($method_name) =head3 $metarole->get_before_method_modifiers($method_name) Given a method name, returns a list of the appropriate modifiers for that method. =head3 $metarole->get_override_method_modifier($method_name) Given a method name, returns the override method modifier for that method, if it has one. =head2 Introspection =head3 Moose::Meta::Role->meta This will return a L<Class::MOP::Class> instance for this class. =head1 BUGS See L<Moose/BUGS> for details on reporting bugs. =head1 AUTHORS =over 4 =item * Stevan Little <stevan.little@iinteractive.com> =item * Dave Rolsky <autarch@urth.org> =item * Jesse Luehrs <doy@tozt.net> =item * Shawn M Moore <code@sartak.org> =item * יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org> =item * Karen Etheridge <ether@cpan.org> =item * Florian Ragwitz <rafl@debian.org> =item * Hans Dieter Pearcey <hdp@weftsoar.net> =item * Chris Prather <chris@prather.org> =item * Matt S Trout <mst@shadowcat.co.uk> =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2006 by Infinity Interactive, Inc. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut