Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rakudo doesn't implement 'handles' (but used to) #1790

Closed
p6rt opened this issue May 27, 2010 · 10 comments
Closed

Rakudo doesn't implement 'handles' (but used to) #1790

p6rt opened this issue May 27, 2010 · 10 comments
Labels

Comments

@p6rt
Copy link

p6rt commented May 27, 2010

Migrated from rt.perl.org#75386 (status was 'resolved')

Searchable as RT75386$

@p6rt
Copy link
Author

p6rt commented May 27, 2010

From @masak

<masak> rakudo​: class A { has @​.contents handles <elems> }; say
A.new(​:contents(1, 2, 3)).elems
<p6eval> rakudo e40ee4​: OUTPUT«1␤»
* masak submits rakudobug
<jnthn> masak​: handles nyi
<masak> it used to be i :(
<masak> hm, perhaps an example with a method not already in Any would
be better... :)
<masak> rakudo​: class A { has $str handles <uc> }; say A.new.uc
<p6eval> rakudo e40ee4​: OUTPUT«Method 'uc' not found for invocant of
class 'A' [...]

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

From maxim4d@gmail.com

created during today's hackmeet with Jonathan Worthington.
attached patch (including handles2.t) partially solves the problem (by
adding add_handles_method method to the core). current problem is​: it
seems that handler attributes don't get passed to ast if we use "has $!x
handles ...." syntax. handles3.t fails probably for this reason. needs
more investigation.

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

From maxim4d@gmail.com

handles.diff
diff --git a/build/Makefile.in b/build/Makefile.in
index 62606c0..a3330ee 100644
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -170,6 +170,7 @@ CORE_SOURCES = \
   src/core/metaops.pm \
   src/core/operators.pm \
   src/glue/subset.pm \
+  src/glue/handles.pm \
   src/cheats/trait-export.pm \
   src/cheats/num.pm \
   src/cheats/eval.pm \
diff --git a/src/Perl6/Actions.pm b/src/Perl6/Actions.pm
index 011230d..6f8428a 100644
--- a/src/Perl6/Actions.pm
+++ b/src/Perl6/Actions.pm
@@ -919,6 +919,11 @@ sub declare_variable($/, $past, $sigil, $twigil, $desigilname, $trait_list) {
         %attr_info<accessor> := $twigil eq '.' ?? 1 !! 0;
         %attr_info<rw>        := $trait_list && has_compiler_trait_with_val($trait_list, '&trait_mod:<is>', 'rw') ?? 1 !! 0;
         @PACKAGE[0].attributes.push(%attr_info);
+        my $has_handles := has_compiler_trait($trait_list, '&trait_mod:<handles>');
+        if $has_handles {
+            %attr_info<handles> := $has_handles[0];
+        }
+
 
         # If no twigil, note $foo is an alias to $!foo.
         if $twigil eq '' {
diff --git a/src/Perl6/Compiler/Package.pm b/src/Perl6/Compiler/Package.pm
index c8b7149..0e1fa67 100644
--- a/src/Perl6/Compiler/Package.pm
+++ b/src/Perl6/Compiler/Package.pm
@@ -177,6 +177,10 @@ method finish($block) {
             $_<build>.named('build');
             $attr.push($_<build>);
         }
+        if $_<handles> {
+            $_<handles>.named('handles');
+            $attr.push($_<handles>);
+        }
         $decl.push(PAST::Op.new(
             :pasttype('callmethod'),
             :name('add_attribute'),
diff --git a/src/metamodel/Attribute.nqp b/src/metamodel/Attribute.nqp
index cfe96ca..ef48aa3 100644
--- a/src/metamodel/Attribute.nqp
+++ b/src/metamodel/Attribute.nqp
@@ -71,6 +71,9 @@ method compose($package) {
     }
 
     # XXX Handles...
+    if $!handles {
+        add_handles_method($package, $!name, $!handles);
+    }
 }
 
 # vim: ft=perl6

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

From maxim4d@gmail.com

use v6;

#use Test;

#plan 20;

class Foo {
  has $!x;
};

class Bar {
  method bar { say "bar"; }
  method bar1 { say "bar1"; }
  method bar2 { say "bar2"; }
  method bar3 { say "bar3"; }
  method bar4 { say "bar4"; }
  method bar5 { say "bar5"; }
  method bar6 { say "bar6"; }
  method bar7 { say "bar7"; }
}

sub add_handles_method_helper($metaclass, $attr, $meth-name, $meth-rename = $meth-name) {
  $metaclass.add_method($metaclass, $meth-name, (method (|$c) {
  pir​::getattribute__PPS(self, $attr)."$meth-rename"(|$c);
  }).clone() );
}

sub add_handles_method($metaclass, $attr_name, $expr) {
  for ($expr) -> $x {
  given $x {
  when Str { add_handles_method_helper($metaclass, $attr_name, $x); }
  when Parcel {
  for $x.list -> $x { add_handles_method_helper($metaclass, $attr_name, $x); }
  }
  when Pair {
  add_handles_method_helper($metaclass, $attr_name, $x.key, $x.value);
  }
  default { die sprintf("add_handles_method can't handle %s in list", $x.WHAT); }
  }
  }
}

say "String​:";
add_handles_method(Foo.HOW, '$!x', 'bar');
Foo.new(x => Bar.new).bar();

say "Parcel​:";
add_handles_method(Foo.HOW, '$!x', <bar1 bar2>);
my $y = Foo.new(x => Bar.new);
$y.bar1();
$y.bar2();

say "Pair​:";
add_handles_method(Foo.HOW, '$!x', ('bar3' => 'bar4'));
Foo.new(x => Bar.new).bar3();

say "List​:";
add_handles_method(Foo.HOW, '$!x', ('bar5', 'bar6', 'bar7'));
my $z = Foo.new(x => Bar.new);
$z.bar5();
$z.bar6();
$z.bar7();

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

From maxim4d@gmail.com

handles.pm

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

From maxim4d@gmail.com

use v6;

#use Test;

#plan 20;

class Foo {
  has $!x handles 'bar';
  has $!y handles <bar1 bar2>;
  has $!z handles ('bar3' => 'bar4');
  has $!w handles ('bar5', 'bar6', 'bar7');
}

class Bar {
  method bar { say "bar"; }
  method bar1 { say "bar1"; }
  method bar2 { say "bar2"; }
  method bar3 { say "bar3"; }
  method bar4 { say "bar4"; }
  method bar5 { say "bar5"; }
  method bar6 { say "bar6"; }
  method bar7 { say "bar7"; }
}

say "String​:";
Foo.new(x => Bar.new).bar();

say "Parcel​:";
my $y = Foo.new(x => Bar.new);
$y.bar1();
$y.bar2();

say "Pair​:";
Foo.new(x => Bar.new).bar3();

say "List​:";
my $z = Foo.new(x => Bar.new);
$z.bar5();
$z.bar6();
$z.bar7();

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Jun 19, 2010

From @jnthn

On Sat Jun 12 13​:42​:18 2010, maard wrote​:

created during today's hackmeet with Jonathan Worthington.
attached patch (including handles2.t) partially solves the problem (by
adding add_handles_method method to the core). current problem is​: it
seems that handler attributes don't get passed to ast if we use "has $!x
handles ...." syntax. handles3.t fails probably for this reason. needs
more investigation.

Thanks, after a couple of tweaks I have applied the patch. We now pass
the first 26 (out of 60) tests in delegation.t, and that probably covers
the most common cases of handles. But we used to pass the whole file in
alpha, so I'll leave this ticket open to track the issue until all cases
are working again.

Thanks,

Jonathan

@p6rt
Copy link
Author

p6rt commented Jun 20, 2010

From @jnthn

On Thu May 27 10​:52​:50 2010, masak wrote​:

<masak> rakudo​: class A { has @​.contents handles <elems> }; say
A.new(​:contents(1, 2, 3)).elems
<p6eval> rakudo e40ee4​: OUTPUT«1␤»
* masak submits rakudobug
<jnthn> masak​: handles nyi
<masak> it used to be i :(
<masak> hm, perhaps an example with a method not already in Any would
be better... :)
<masak> rakudo​: class A { has $str handles <uc> }; say A.new.uc
<p6eval> rakudo e40ee4​: OUTPUT«Method 'uc' not found for invocant of
class 'A' [...]

Now​:

class A { has @​.contents handles <elems> };
say A.new(​:contents(1, 2, 3)).elems
3

And​:

class A { has $str handles <uc> }; say A.new(str => "lol").uc
LOL

Plus we pass all the other cases alpha did for handles now, and the
tests are turned on, so resolving ticket.

Jonathan

@p6rt
Copy link
Author

p6rt commented Jun 20, 2010

@jnthn - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Jun 20, 2010
@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant