Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re^2: No garbage collection for my-variables

by moritz (Cardinal)
on Sep 16, 2008 at 18:55 UTC ( [id://711774]=note: print w/replies, xml ) Need Help??


in reply to Re: No garbage collection for my-variables
in thread No garbage collection for my-variables

There's much more perlish reason not modify the arguments of sub by default. If you don't, you can write stuff like this:
other_function(decode 'latin-1', 'string_literal')) # and if you want to change a variable $var = decode('latin-1', $var);

On the other hand if you do change the the arguments of the sub, the first one requires another variable, which is a real kludge (visually, at least)

do { my $var = 'string_literal'; decode('latin-1', $var); other_function($var); } # and the other one decode('latin-1', $var)

Replies are listed 'Best First'.
Re^3: No garbage collection for my-variables
by BrowserUk (Patriarch) on Sep 16, 2008 at 21:57 UTC

    I think that you've overplayed the case. Using a do block instead of an anonymous block makes it look more complicated than it is.

    Even wrapping a local var in a bare block is rarely necessary. Most code is nested at some level in a if or while or other loop block or subroutine body.

    On the rare occasions that it is at the top level of a program or module, if you really want it to be garbage collected, undef is better (in that it will actually achieve something) anyway.

    Even the use of a constant is a emphasising the rare case. Mostly data is read in from external sources and is in a variable already, so:

    while( my $var = <$fh> ) { mutate( $var ); use( $var ); }

    is hardly onerous, but even that can be avoided. Thanks to perl's context sensitivity, you can have the best of both worlds. For the simple case, subroutines behave as passthru pass-by-value, but when the need arises to minimise memory allocation and copying, using it ina void context does the right thing:

    #! perl -slw use strict; sub mutates { my $ref = defined wantarray ? \shift : \$_[ 0 ]; $$ref =~ s[(?<=\b[^ ])([^ ]+)(?=[^ ]\b)][scalar reverse $1]ge; return $$ref if defined wantarray; return; } sub doSomething { print shift; } doSomething( mutates( 'antidisestablishmentarismania' ) ); my $var = 'The quick brown fox jumps over the lazy dog'; mutates( $var ); doSomething( $var ); __END__ c:\test>junk ainamsiratnemhsilbatsesiditna The qciuk bworn fox jpmus oevr the lzay dog

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks to perl's context sensitivity, you can have the best of both worlds. For the simple case, subroutines behave as passthru pass-by-value, but when the need arises to minimise memory allocation and copying, using it ina void context does the right thing

      Now that's surely tempting, but could lead to rather odd situations:

      sub do_stuff { ... do_other_stuff($variable); # remove that debugging statement, and do_other_stuff # will behave very differently if do_stuff is not # called in void context print "still here\n"; }

      Admittedly that's a fairly artificial situation and won't show up in real code very often, but if it does it's very nasty to debug.

      Designing interfaces around performance optimizations and memory management oddities just doesn't seem right to me.

        If that function is called in a non-void context, it is returning the result of the "debug statement", which seems more than a little artificial.

        If the function is ever called in a non-void context, it will be because it returns something useful. If the return statement (or the fall-off-the-end expression) is omitted, then the function isn't going to work the way it is intended anyway, so any other error is academic. Just another justifiction I'm afraid.

        Plenty of languages use pass-by-reference, and thousands of programmers and millions of programs use it every day without dire consequences.

        Designing interfaces around performance optimizations and memory management oddities just doesn't seem right to me.

        You seem to be saying: Oh, I mustn't use this language feature, because that would make my code more efficient and that would be an optimisation and it might be premature!

        Why does Text::CSV_XS exist? Or the XS version of List::Util? Or ...

        It's changing your transatlantic flight path to take full advantage of (or avoid) the gulf stream. It's shutting off the fuel supply to the injectors when the engine is on overrun. Removing your roof rack when you aren't using it.

        Perl is a context sensitive language, it is a uniquie and powerful defining feature. Perl programmers need to be aware of it, understand it and use it. Pretending it doesn't exists, or running scared of it you might as well use VB.

        It drives me nuts. I use Perl, because I like the language. But there are people around here won't use map or grep; or statement modifiers; or unless or until. They eshew aliasing; context sensitivity; autovivification; the implicit variables: it and these. They want everything OO; will jump through hoops creating singleton classes, "to avoid globals" and end up with nothing more than lexically-scoped globals (eg. our). Use ReadOnly variables as constants instead of constants.

        Why bother using Perl?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^3: No garbage collection for my-variables
by Porculus (Hermit) on Sep 16, 2008 at 21:57 UTC
    Agreed a thousand times over. If I had a penny for every time I'd been forced to write tedious and ugly code because chomp modifies its argument instead of returning the chomped version, I'd have several pennies.
      Are
      chomp( my $var = <$fh> );

      and

      chomp( my $dst = $src );
      really more tedious and uglier than
      my $var = chomp( scalar ( <$fh> ) );

      and

      my $dst = chomp( $src );

        They are. funcall(<variable assignment>) is a useful idiom in programming languages where assigment returns (an alias to) the value of the variable, but it is counter-intuitive at first. Even though I have been programming in Perl and curly brace block syntax languages for years, I still find it hard to read -- mostly because when you normally delimit my with braces, you create a new lexical scope. That's what chomp(my $foo = bar) still seems to be, even if I know better and use the idiom frequently.

        Not only that, but it is not obvious that the value of $var in chomp(my $var = <$fh>) is being modified at all! After all, assignment, if used in other contexts, returns the value, not a reference to it. my $foo = $bar = 1 doesn't create a reference in $foo, but sets the value of both variables to 1. In fact, I am not sure what the underlying mechanism is. Does it work because assignment returns an alias similar to aliased values in @_ in function calls?

        Side-effect free chomp has no similar conceptual problems.

        --
        say "Just Another Perl Hacker";

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-19 03:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found