YAPC::EU and Perl 6 Roles
Giving a talk about roles at YAPC::EU in Lisbon and I'm a bit stuck on how to translate a Perl 5 example into Perl 6. Basically, Imagine a PracticalJoke class which has fuse() and explode methods(). It needs the timed fuse() from a Bomb role and a non-lethal explode() from a Spouse role, though each role provides both methods. In Moose, it's easy: package PracticalJoke; use Moose; with 'Bomb' = { excludes = 'explode' }; 'Spouse' = { excludes = 'fuse' }; Try as I might, I can't figure out how to translate that into Perl 6. I have the following: role Bomb { method fuse (){ say '3 .. 2 .. 1 ..' } method explode () { say 'Rock falls. Everybody dies!' } } role Spouse { method fuse (){ sleep rand(20); say Now! } method explode () { say 'You worthless piece of junk! Why I should ...' } } class PracticalJoke does Bomb does Spouse { } Nothing I see in S14 (http://perlcabal.org/syn/S14.html) seems to cover this case. I can't declare them as multis as they have the same signature. There's a note that one can simply to write a class method that overrides the conflicting role methods, perhaps figuring out which role method to call, but I don't understand how a particular role's methods would be called here. Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Tech blog- http://use.perl.org/~Ovid/journal/ Twitter - http://twitter.com/OvidPerl Official Perl 6 Wiki - http://www.perlfoundation.org/perl6
Re: YAPC::EU and Perl 6 Roles
On Tue, Jul 7, 2009 at 2:48 AM, Ovidpubliustemp-perl6langua...@yahoo.com wrote: Giving a talk about roles at YAPC::EU in Lisbon and I'm a bit stuck on how to translate a Perl 5 example into Perl 6. Basically, Imagine a PracticalJoke class which has fuse() and explode methods(). It needs the timed fuse() from a Bomb role and a non-lethal explode() from a Spouse role, though each role provides both methods. In Moose, it's easy: package PracticalJoke; use Moose; with 'Bomb' = { excludes = 'explode' }; 'Spouse' = { excludes = 'fuse' }; Try as I might, I can't figure out how to translate that into Perl 6. I have the following: role Bomb { method fuse () { say '3 .. 2 .. 1 ..' } method explode () { say 'Rock falls. Everybody dies!' } } role Spouse { method fuse () { sleep rand(20); say Now! } method explode () { say 'You worthless piece of junk! Why I should ...' } } class PracticalJoke does Bomb does Spouse { } Nothing I see in S14 (http://perlcabal.org/syn/S14.html) seems to cover this case. I can't declare them as multis as they have the same signature. There's a note that one can simply to write a class method that overrides the conflicting role methods, perhaps figuring out which role method to call, but I don't understand how a particular role's methods would be called here. I believe that the official word is to say: class PracticalJoke does Bomb does Spouse { method fuse () { Bomb::fuse } method explode () { Spouse::explode } } Personally, I agree that some sort of ability to exclude individual methods from Roles, such as what Moose does, would be beneficial; but this is an old argument that has been hashed out many times before. -- Jonathan Dataweaver Lang
Re: YAPC::EU and Perl 6 Roles
Ovid wrote: Giving a talk about roles at YAPC::EU in Lisbon Hey, me too! :-) and I'm a bit stuck on how to translate a Perl 5 example into Perl 6. Basically, Imagine a PracticalJoke class which has fuse() and explode methods(). It needs the timed fuse() from a Bomb role and a non-lethal explode() from a Spouse role, though each role provides both methods. In Moose, it's easy: package PracticalJoke; use Moose; with 'Bomb' = { excludes = 'explode' }; 'Spouse' = { excludes = 'fuse' }; Try as I might, I can't figure out how to translate that into Perl 6. I have the following: role Bomb { method fuse (){ say '3 .. 2 .. 1 ..' } method explode () { say 'Rock falls. Everybody dies!' } } role Spouse { method fuse (){ sleep rand(20); say Now! } method explode () { say 'You worthless piece of junk! Why I should ...' } } class PracticalJoke does Bomb does Spouse { } Nothing I see in S14 (http://perlcabal.org/syn/S14.html) seems to cover this case. I can't declare them as multis as they have the same signature. There's a note that one can simply to write a class method that overrides the conflicting role methods, perhaps figuring out which role method to call, but I don't understand how a particular role's methods would be called here. The spec is right in that you need to write a method in the class that decides what to do. This will look something like: method fuse() { self.Bomb::fuse() } Or also if you like you can probably get away with: method fuse() { $.Bomb::fuse() } But be aware that then you're forcing item context on the return value. Note that this is NYI in Rakudo, but I hope to do it fairly soon (before YAPC::EU). Thanks, Jonathan
Re: YAPC::EU and Perl 6 Roles
Jon Lang wrote: I believe that the official word is to say: class PracticalJoke does Bomb does Spouse { method fuse () { Bomb::fuse } method explode () { Spouse::explode } } This way won't work, because: * It's doing a sub call to something that's a method * The lookup won't work unless the method has our (package) scope * * Even in that case, the invocant isn't being passed so you'll get a wrong number of parameters error Thanks, Jonathan * I somewhat suspect calling a routine in a role using the role name as a namespace identifier should be banned anyway, since we'd have no clue what to do with references to $?CLASS, which is meant to be generic.
Re: YAPC::EU and Perl 6 Roles
On Jul 7, 2009, at 07:34 , Jonathan Worthington wrote: Jon Lang wrote: I believe that the official word is to say: class PracticalJoke does Bomb does Spouse { method fuse () { Bomb::fuse } method explode () { Spouse::explode } } This way won't work, because: * It's doing a sub call to something that's a method * The lookup won't work unless the method has our (package) scope * * Even in that case, the invocant isn't being passed so you'll get a wrong number of parameters error I was trying to figure out how to do it with nextsame, but that's not looking very simple. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon universityKF8NH PGP.sig Description: This is a digitally signed message part
Re: YAPC::EU and Perl 6 Roles
Brandon S. Allbery KF8NH wrote: On Jul 7, 2009, at 07:34 , Jonathan Worthington wrote: Jon Lang wrote: I believe that the official word is to say: class PracticalJoke does Bomb does Spouse { method fuse () { Bomb::fuse } method explode () { Spouse::explode } } This way won't work, because: * It's doing a sub call to something that's a method * The lookup won't work unless the method has our (package) scope * * Even in that case, the invocant isn't being passed so you'll get a wrong number of parameters error I was trying to figure out how to do it with nextsame, but that's not looking very simple. Interesting thought, but the problem is that: role R { method a() { }; method b() { } } class C does R { method b() { } } In this case, method b from the role never gets composed into the class, thanks to the method b in the class. (This is the flattening aspect of role composition at work). In fact, the composed method behaves pretty much as if it had been defined in the class itself. So the method b in the role doesn't exist in the candidate list that we walk when doing deference. From Rakudo: role R { method a() { }; method b() { } } class C does R { method b() { } } say C.WALK(:nameb).elems 1 On the other hand, if they were multis then they get added to the multi candidate list and therefore you can nextsame into them. Again from Rakudo: role R { multi method b() { say lol in role } } class C does R { multi method b() { say oh hai in class; nextsame } } C.new.b oh hai in class lol in role And role ones beat parents in the ordering too... role R { multi method b() { say lol in role; nextsame } } class P { method b() { say parent ftw } } class C is P does R { multi method b() { say oh hai in class; nextsame } } C.new.b oh hai in class lol in role parent ftw (Note to the bored: feel free to beat me to adding something like these last two to the spectests...I'm away for the afternoon/evening.) Thanks, Jonathan
Re: YAPC::EU and Perl 6 Roles
On Jul 7, 2009, at 08:13 , Jonathan Worthington wrote: Brandon S. Allbery KF8NH wrote: I was trying to figure out how to do it with nextsame, but that's not looking very simple. On the other hand, if they were multis then they get added to the multi candidate list and therefore you can nextsame into them. Again from Rakudo: role R { multi method b() { say lol in role } } class C does R { multi method b() { say oh hai in class; nextsame } } C.new.b oh hai in class lol in role But even then that's only half of it; we want a() from one role and b() from another, when both roles do a() and b(). Looks painful to me. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon universityKF8NH PGP.sig Description: This is a digitally signed message part
Re: YAPC::EU and Perl 6 Roles
Brandon S. Allbery KF8NH wrote: On Jul 7, 2009, at 08:13 , Jonathan Worthington wrote: Brandon S. Allbery KF8NH wrote: I was trying to figure out how to do it with nextsame, but that's not looking very simple. On the other hand, if they were multis then they get added to the multi candidate list and therefore you can nextsame into them. Again from Rakudo: role R { multi method b() { say lol in role } } class C does R { multi method b() { say oh hai in class; nextsame } } C.new.b oh hai in class lol in role But even then that's only half of it; we want a() from one role and b() from another, when both roles do a() and b(). Looks painful to me. Right, and deference is the Wrong Tool For The Job in that case. The right answer is more like: class C does R1 does R2 { method a() { self.R1::a() } method b() { self.R2::b() } } Thanks, Jonathan
r27468 - docs/Perl6/Spec/S32-setting-library
Author: skids Date: 2009-07-07 15:51:58 +0200 (Tue, 07 Jul 2009) New Revision: 27468 Modified: docs/Perl6/Spec/S32-setting-library/Numeric.pod Log: [S32/Numeric] correct parameter name in atan2 method form Modified: docs/Perl6/Spec/S32-setting-library/Numeric.pod === --- docs/Perl6/Spec/S32-setting-library/Numeric.pod 2009-07-07 11:48:11 UTC (rev 27467) +++ docs/Perl6/Spec/S32-setting-library/Numeric.pod 2009-07-07 13:51:58 UTC (rev 27468) @@ -265,7 +265,7 @@ =item atan2 - our Num multi method atan2 ( Num $y: Num $y = 1 ) + our Num multi method atan2 ( Num $y: Num $x = 1 ) our Num multi atan2 ( Num $y, Num $x = 1 ) This second form of Catan computes the arctangent of C$y/$x, and takes
Testing Perl 6 analog to Perl 5's tie.
My patchwork readings lead me to believe I could test Perl 6's tie-like feature with something like the below code, which I don't expect to even compile, what with '???' in places. My question is: am I on the right track? Obviously there are details I haven't nailed down, and any guidance would be appreciated. Thanks! # Scalar is Any does Container does Order class ScalarTester is Scalar { has @.log; multi STORE ( Any $thing ) { @.log.push( STORE = $thing ); nextsame; } multi FETCH() { @.log.push( 'FETCH' ); nextsame; } multi TEMP() { @.log.push( 'TEMP' ); nextsame; } multi infix:= ( ??? ) { @.log.push( 'infix:=' ); nextsame; } multi infix::= ( ??? ) { @.log.push( 'infix::=' ); nextsame; } multi infix:::= ( ??? ) { @.log.push( 'infix:::=' ); nextsame; } multi infix:=:= ( ??? ) { @.log.push( 'infix:=:=' ); nextsame; } # since Scalar does Order, there are ~20 other methods to test. } my $t is ScalarTester; is $t.log, (), 'log is empty'; lives_ok { $t = 'bughunt' }, 'can assign to test scalar'; is $t.log, ( 'STORE' = 'bughunt' ), 'log reflects assignment'; lives_ok { my $discard = $t }, 'can access test scalar'; is $t.log, ( 'STORE' = 'bughunt', 'FETCH' ), 'log reflects access';
Re: YAPC::EU and Perl 6 Roles
On Tue, 7 Jul 2009, Ovid wrote: role Bomb { method fuse (){ say '3 .. 2 .. 1 ..' } method explode () { say 'Rock falls. Everybody dies!' } } role Spouse { method fuse (){ sleep rand(20); say Now! } method explode () { say 'You worthless piece of junk! Why I should ...' } } class PracticalJoke does Bomb does Spouse { } class PracticalJoke { has Bomb $bomb handles fuse; has Spouse $spouse handles explode; } Note that I have no idea where (if anywhere) the type goes in this. Hopefully someone will correct me here. Note that this does not use the roles as roles; it uses them punned as classes. But it does what you asked :). :) - | Name: Tim Nelson | Because the Creator is,| | E-mail: wayl...@wayland.id.au| I am | - BEGIN GEEK CODE BLOCK Version 3.12 GCS d+++ s+: a- C++$ U+++$ P+++$ L+++ E- W+ N+ w--- V- PE(+) Y+++ PGP-+++ R(+) !tv b++ DI D G+ e++ h! y- -END GEEK CODE BLOCK-