Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re^2: Why do I get a "used only once" warning here?

by rovf (Priest)
on Mar 13, 2009 at 14:01 UTC ( [id://750419]=note: print w/replies, xml ) Need Help??


in reply to Re: Why do I get a "used only once" warning here?
in thread Why do I get a "used only once" warning here?

presumably you are storing keys in %MyApp because you intend to check them at some other point in your package.

Actually, I do check them, but not at another point in the package, but at the same. Note the usage of ||=.

-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re^3: Why do I get a "used only once" warning here?
by bellaire (Hermit) on Mar 13, 2009 at 14:11 UTC
    Ah, I missed the side-effect of the function, sorry. In fairness, Perl has no way of knowing (as I should have from the name of the function, "log") that your function has a side-effect. If this function were to simply return a value, then the warning would make sense, because you would be storing a value and never using it. With the side-effect, though, everything becomes clear.

    If you really want that syntax, then you should turn warnings off as others have suggested. Alternatively, you could use a syntax which mentions the variable twice. I don't know if the fact that I missed the meaning of your code is indicative of unclear syntax, or if it's just me being blind this morning.
      erl has no way of knowing (as I should have from the name of the function, "log") that your function has a side-effect.

      This is correct, but if we use an operator like ||=, &&=, .= and so on, implies that at least at that statement, the value of the variable is read AND written, so one could argue that this means that the variable is used at least twice. This has nothing to do with whether or not the expression on the right-hand side has side effects. In other words:

      $P::x ||= (f(),1);
      produces a warning, while the equivalent
      $P::x = $P::x || (f(),1);
      does not.

      -- 
      Ronald Fischer <ynnor@mm.st>
        ... one could argue that this means that the variable is used at least twice.

        The warning is about the human-visible name, not the storage location.

        I understand, and you're right of course. This doesn't have to do with the semantics of the statement. It's an interesting case, and I think it illustrates that the logic for generating this warning is simplistic (as chromatic points out). In fairness, I think that's the intent of warnings: They aren't errors, they simply bring your attention to something that, in the many cases, may indicate a potential error. In this particular case, you know better, so the warning doesn't make sense.

        If you do decide to use an alternative syntax, FWIW I'd probably use an alternative syntax like:
        if (not $P::x) { $P::x = 1; f(); }
        Not only is this considerably more understandable, IMO, but I ran some benchmarks, and the speed difference between this and the form using ||= is negligible. On the other hand, using the expanded syntax with || is (surprisingly!) slower.
        use strict; use warnings; use Benchmark qw( timethese cmpthese ); my $results = timethese( 5000, { orig => sub { delete $P::x{some_key}; for ( 1 .. 1000 ) { $P::x{some_key} ||= ( f(), 1 ); } }, alt_1 => sub { delete $P::x{some_key}; for ( 1 .. 1000 ) { $P::x{some_key} = $P::x{some_key} || ( f(), 1 ); } }, alt_2 => sub { delete $P::x{some_key}; for ( 1 .. 1000 ) { if ( not $P::x{some_key} ) { $P::x{some_key} = 1; f(); } } }, } ); cmpthese($results); sub f() { #No op. }
        Benchmark: timing 5000 iterations of alt_1, alt_2, orig... alt_1: 3 wallclock secs ( 3.08 usr + 0.00 sys = 3.08 CPU) @ 16 +23.38/s (n=5000) alt_2: 2 wallclock secs ( 1.29 usr + 0.00 sys = 1.29 CPU) @ 38 +75.97/s (n=5000) orig: 1 wallclock secs ( 1.25 usr + 0.00 sys = 1.25 CPU) @ 40 +00.00/s (n=5000) Rate alt_1 alt_2 orig alt_1 1623/s -- -58% -59% alt_2 3876/s 139% -- -3% orig 4000/s 146% 3% --

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://750419]
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: (9)
As of 2024-03-28 09:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found