Skip Menu |

This queue is for tickets about the Params-Lazy CPAN distribution.

Report information
The Basics
Id: 87940
Status: resolved
Priority: 0/
Queue: Params-Lazy

People
Owner: Nobody in particular
Requestors: perl [...] toby.ink
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Leaky abstraction - using @_ within the lazy evaluated expression:
sub delay { say 1; force($_[0]); say 3; } use Params::Lazy delay => "^"; sub foo { delay(say $_[0]); } foo(2); I'd expect output to look like: 1 2 3 But it's actually more like: 1 SCALAR(0x9273ea0) 3 This is probably impossible to get working right; if it were documented as another limitation, I'd consider the issue resolved.
From: fraserbn [...] gmail.com
On Mon Aug 19 08:21:17 2013, TOBYINK wrote: Show quoted text
> sub delay { > say 1; > force($_[0]); > say 3; > } > > use Params::Lazy delay => "^"; > > sub foo { > delay(say $_[0]); > } > > foo(2); > > > I'd expect output to look like: > > 1 > 2 > 3 > > But it's actually more like: > > 1 > SCALAR(0x9273ea0) > 3 > > This is probably impossible to get working right; if it were > documented as another limitation, I'd consider the issue resolved.
Thank you for my first bug report! :D This might actually be fixable[*], but I can't decide whenever the behavior would be correct. It'd leave @_ inconsistent with the rest of the global variables: sub delay; use Params::Lazy delay => '^'; sub delay { my $d = shift; local @_ = "happy fun times"; local $_ = "happier fun times"; say force $d; } @_ = "original"; $_ = "more so"; delay($_); delay(@_); For $_, you'd see the value that the sub is explicitly setting up, but for @_, you'd see the value from the upper scope. On the other hand, I can see how having the caller's @_ would be useful. This is tricky. A possible workaround, which I haven't tried, is to add more evil into the mix and try using Scope::Upper. Perhaps I need to add a force_with_caller_args function. But with a less silly name. [*] famous last words, considering I haven't even tried yet :)
From: fraserbn [...] gmail.com
On Mon Aug 19 21:03:38 2013, Hugmeir wrote: Show quoted text
> On Mon Aug 19 08:21:17 2013, TOBYINK wrote:
> > sub delay { > > say 1; > > force($_[0]); > > say 3; > > } > > > > use Params::Lazy delay => "^"; > > > > sub foo { > > delay(say $_[0]); > > } > > > > foo(2); > > > > > > I'd expect output to look like: > > > > 1 > > 2 > > 3 > > > > But it's actually more like: > > > > 1 > > SCALAR(0x9273ea0) > > 3 > > > > This is probably impossible to get working right; if it were > > documented as another limitation, I'd consider the issue resolved.
> > Thank you for my first bug report! :D > > This might actually be fixable[*], but I can't decide whenever the > behavior would be correct. It'd leave @_ inconsistent with the rest of > the global variables: > > sub delay; > use Params::Lazy delay => '^'; > > sub delay { > my $d = shift; > local @_ = "happy fun times"; > local $_ = "happier fun times"; > say force $d; > } > > @_ = "original"; > $_ = "more so"; > delay($_); > delay(@_); > > For $_, you'd see the value that the sub is explicitly setting up, but > for @_, you'd see the value from the upper scope. > > On the other hand, I can see how having the caller's @_ would be > useful. This is tricky. A possible workaround, which I haven't tried, > is to add more evil into the mix and try using Scope::Upper. > > Perhaps I need to add a force_with_caller_args function. But with a > less silly name. > > [*] famous last words, considering I haven't even tried yet :)
Fixed in version 0.004. That was harder than I originally anticipated! :D Having the delayed expression see the caller's @_ is now the default; the previous behavior is still available, by using 'no Params::Lazy q{caller_args};' before declaring the function.