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

Strange stateful results when calling a method containing a .^can call in Rakudo #2295

Closed
p6rt opened this issue Dec 13, 2010 · 6 comments
Closed
Labels

Comments

@p6rt
Copy link

p6rt commented Dec 13, 2010

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

Searchable as RT80694$

@p6rt
Copy link
Author

p6rt commented Dec 13, 2010

From @masak

<masak> rakudo​: class A { method foo { 'abc' }; A.^add_method('bar',
A.^can('foo')); }; my $x= A.new(); say $x.bar(); say $x.bar()
<p6eval> rakudo : OUTPUT«abc␤No candidates found to invoke for method
'foo' on object of type 'A'␤[...]
<masak> <takadonet> only works once :(
* masak submits rakudobug
<masak> if jnthn were here, he'd say that this result isn't so
strange; becuase .^can gives the dispatcher to the 'foo' method(s).
<masak> call it once, shame on... shame on you. call me tw... can't
get called again
<takadonet> it's strange
<masak> as with string encodings, dispatchers are there whether you're
aware of them or not, and whether you want/like them or not.

@p6rt
Copy link
Author

p6rt commented Dec 13, 2010

From @jnthn

On 13/12/2010 21​:08, Carl Mäsak (via RT) wrote​:

# New Ticket Created by "Carl Mäsak"
# Please include the string​: [perl #​80694]
# in the subject line of all future correspondence about this issue.
#<URL​: http://rt.perl.org/rt3/Ticket/Display.html?id=80694>

<masak> rakudo​: class A { method foo { 'abc' }; A.^add_method('bar',
A.^can('foo')); }; my $x= A.new(); say $x.bar(); say $x.bar()
<p6eval> rakudo : OUTPUT«abc␤No candidates found to invoke for method
'foo' on object of type 'A'␤[...]
<masak> <takadonet> only works once :(
* masak submits rakudobug
<masak> if jnthn were here, he'd say that this result isn't so
strange; becuase .^can gives the dispatcher to the 'foo' method(s).
He might even defend it as correct. After all, a dispatcher has state -
what .^can returns is even spec'd as an iterator. If you don't want a
dispatcher, use .^methods. Of course, then you can't expect deferral to
work within the method fetched that way. :-)

/jnthn

@p6rt
Copy link
Author

p6rt commented Dec 13, 2010

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

@p6rt
Copy link
Author

p6rt commented Dec 13, 2010

From @masak

masak (>>), jnthn (>)​:

<masak> rakudo​: class A { method foo { 'abc' }; A.^add_method('bar',
A.^can('foo')); }; my $x= A.new(); say $x.bar(); say $x.bar()
<p6eval> rakudo : OUTPUT«abc␤No candidates found to invoke for method
'foo' on object of type 'A'␤[...]
<masak> <takadonet> only works once :(
* masak submits rakudobug
<masak> if jnthn were here, he'd say that this result isn't so
strange; becuase .^can gives the dispatcher to the 'foo' method(s).

He might even defend it as correct. After all, a dispatcher has state -
what .^can returns is even spec'd as an iterator. If you don't want a
dispatcher, use .^methods. Of course, then you can't expect deferral to
work within the method fetched that way. :-)

So... what's the "right" way to do the above .^add_method? Which construct, if not .^can, should
be used to directly refer to exactly the .foo method in A? (Such that it works the same each
time, without hidden state.)

@p6rt
Copy link
Author

p6rt commented Jul 9, 2015

From @jnthn

On Mon Dec 13 12​:08​:41 2010, masak wrote​:

<masak> rakudo​: class A { method foo { 'abc' }; A.^add_method('bar',
A.^can('foo')); }; my $x= A.new(); say $x.bar(); say $x.bar()
<p6eval> rakudo : OUTPUT«abc␤No candidates found to invoke for method
'foo' on object of type 'A'␤[...]
<masak> <takadonet> only works once :(
* masak submits rakudobug
<masak> if jnthn were here, he'd say that this result isn't so
strange; becuase .^can gives the dispatcher to the 'foo' method(s).
<masak> call it once, shame on... shame on you. call me tw... can't
get called again
<takadonet> it's strange
<masak> as with string encodings, dispatchers are there whether you're
aware of them or not, and whether you want/like them or not.

These days, .^can always returns a Parcel (List after GLR, I suspect). I can't get any weird stateful behavior any more; it consistently fails to work. The correct spelling is .^lookup, and this consistently works​:

class A {
  method foo { 'abc' };
  A.^add_method('bar', A.^lookup('foo'));
}
say A.new().bar();

Though you should really do it at BEGIN time to not make yourself performance and pre-comp issues.

Added a test that .^can now fails right off, and .^lookup works out, to S12-introspection/meta-class.t.

@p6rt p6rt closed this as completed Jul 9, 2015
@p6rt
Copy link
Author

p6rt commented Jul 9, 2015

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

@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