Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^4: Local for lexicals (KISS)

by JadeNB (Chaplain)
on Aug 10, 2009 at 21:29 UTC ( [id://787416]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Local for lexicals (KISS)
in thread Local for lexicals

Fixing your code so that it works and also demonstrates that things don't stop being tied shows that my code works fine with such things …
I agree that my code isn't a very good implementation of a tied variable, but it is what I meant (UPDATE 3: except for the silly out-of-place $class), and fixing it breaks the example. :-) (Your code doesn't quite fix it, because you try to assign to a read-only variable. Something like sub Tie::TIESCALAR { return bless \( my $o = $_[1] ) => $_[0] } would be better, I think.)

As a less offensive example, if I replace your STORE by

sub Tie::STORE { ${$_[0]} = $_[1] unless defined ${$_[0]} }
then it's clear that the localisation isn't really protecting anything in the inner scope from changing:
tie my $x, 'Tie'; my $f = sub { $x }; { my $scope = tempSet(\$x, 2); print $f->(), "\n"; # => 2 is still tied } $x = 1; print $f->(), "\n"; # => 2 is still tied
Your comment
Yes, in contrast, local is implemented in a way that it temporarily hides the tied nature of the localized scalar.
hits the nail on your head—I want precisely something that has the same effect for lexicals, of setting aside their previous value, whatever that value is, and restoring it undisturbed afterwards. (In particular, $x should not be tied in the inner scope, even if it is outside.)

UPDATE 1: Actually, testing with tie our $x, 'Tie' and an interior local $x seems to show that localisation of globals doesn't behave the way I want, either! (See Re^6: Local for lexicals (untie) for a simpler example.)
UPDATE 2: Changed if defined test to unless defined.

Replies are listed 'Best First'.
Re^5: Local for lexicals (untie)
by tye (Sage) on Aug 10, 2009 at 22:20 UTC
    then the given code blows up
    I agree that my code isn't a very good implementation of a tied variable, but it is what I meant

    Code that doesn't compile (under strict) is what you meant? And it is your STORE that causes things to "blow up". Just to be clear, my code works just fine if given a tied implementation that isn't seriously broken.

    Your code doesn't quite fix it, because you try to assign to a read-only variable

    I ran my code and got no complaints about assigning to read-only variables. Did you get such an error from Perl when running my code? Or are you determining that a read-only variable is being assigned to based on visual inspection of the code? Or did you plug my code into some other example and get that error? This might be a difference between Perl versions. I just kept your TIESCALAR code as close to what you wrote as I could.

    Of course, I could just put my $temp = $x; $x = 2 at the top of the scope and $x = $temp at the end [...] but this isn't completely satisfactory: For example, if $x starts off tied, then it will no longer be after my $temp = $x; $x = $temp.

    You are wrong there as well. my $temp= $x; $x= $temp; doesn't leave $x no longer tied.

    So I have some doubt of what your real requirements are. Yes, local causes a variable to temporarily not be tied (something that I find mostly to be an accident of implementation choice not something that makes sense as an intentional feature). You state that you want this behavior of local (but don't really explain why) but you also think that my code won't work with a tied variable, when it works just fine and you complain that the lexical variable will end up untied when that doesn't happen.

    So I can see wanting code to not "blow up" with "tied variables (probably among other circumstances)". And I can see not wanting the variable to end up untied. But neither of those are problems with my implementation.

    If somebody goes out of their way to tie $x before invoking lambda $x => sub { $x**2 }, then I think they would also be surprised to have that tie have no impact each time sub { $x**2 } gets called.

    - tye        

      If somebody goes out of their way to tie $x before invoking lambda $x => sub { $x**2 }, then I think they would also be surprised to have that tie have no impact each time sub { $x**2 } gets called.
      It seemed ‘obvious’ to me that, after a local $x, I should be able to assume that I'm in the same state as if $x had just been freshly declared, regardless of what happened in the outer scope; but I find this an excellent argument for why that would be a bad way to arrange things.
      I'm sorry, I think that I've given offence. None was meant.
      Code that doesn't compile (under strict) is what you meant? And it is your STORE that causes things to "blow up". Just to be clear, my code works just fine if given a tied implementation that isn't seriously broken.
      The $class, you mean? Yes, that was a silly think-o—sorry. It seems to compile fine with the obvious modification, though.

      My point really was just that throwing a maliciously tied variable at your implementation could break it (a non-point, now that I see that the same is true of local), and I was looking for code that was completely oblivious to the actual variable it was localising.

      Did you get such an error from Perl when running my code?
      Yes, I did, running perl 5.8.9 installed on a Mac via MacPorts. It also makes sense to me by visual inspection (although you are rightly sceptical of my ability to execute code by looking at it): tie my $x, 'Tie', 1 will leave $x tied to \1, and de-referencing that will lead to an assignment like 1 = 2.
      Of course, I could just put my $temp = $x; $x = 2 at the top of the scope and $x = $temp at the end ... but this isn't completely satisfactory: For example, if $x starts off tied, then it will no longer be after my $temp = $x; $x = $temp.
      You are wrong there as well. my $temp= $x; $x= $temp; doesn't leave $x no longer tied.
      Yes, you are right that I am wrong! :-) I assumed that it would destroy tiedness, but (wrongly) didn't test it. What I was thinking—and this is true—is that tied variables don't always survive round trips, in the sense that my $temp = $x; $x = $temp need not leave the value of $x unchanged. (Perhaps a condition on a reasonable implementation of a tied variable is that that doesn't happen, but I think it's true of a lot of existing classes do not satisfy this condition.)
      Yes, local causes a variable to temporarily not be tied (something that I find mostly to be an accident of implementation choice not something that makes sense as an intentional feature)
      This is not true on my Perl:
      sub TIESCALAR { bless \my $o => $_[0] } sub FETCH { print "Tied\n" } sub STORE {} tie our $x => 'main'; { local $x; $x; # => Tied }
      What does ‘work’ (for my definition of working!) is going the other way:
      our $x; { local $x; tie $x => 'main'; } $x; # nothing (except a warning about void context)
        I'm sorry, I think that I've given offence. None was meant.

        No, I took no offense.

        I suspect that the effect of local on tied scalar variables has changed since Perl 5.0. Perhaps the previous treatment was considered a bug.

        - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://787416]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-19 16:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found