in reply to Re: Perl scoping not logical...?
in thread Perl scoping not logical...?

Well, the problem is that I am really wanting a lexical named sub but currently, subs are still in the stage of being global to the entire program (variables used to be like that too, but then there used to not be subs, so subs started lower...that's why they're 'sub's. ;-}

I certainly don't want the routine *compiled* each time I invoke the routine. I want it to use the same lexical frame as the variables that the sub is defined in. The only way to do it in perl is to use anonymous subroutines and put a reference into a variable and use an indirect call $var_func->(args), which is not as visually as clear a syntax (in my mind) as "func(args)".

The locals aren't really being crushed...their just in flux....(duplicated, really)....

I took a large chunk of 'inline' code that seemed like it should have its own function and shoved it into a subroutine and started by passing in all of the variables that were needed -- initially about 6 args, with about 3 that were only used inside the code block (so they could become local vars in the subroutine).

Wasn't ideal, but that's why I began shifting and playing with how the code was organized and some params were converted, while some (in the example posted) were still being passed as params...but I was changing them slowly as I was tracking down references in the code and seeing how long the variables needed to be "active".

But that's also how I ended up with a named subroutine -- the subroutine was named for the "functional work" that it was doing. In cleaning/refactoring code, I try to go through and look at parts that are either not clear or are too long or just don't look right. One step in that for me in my own code is "saying what the code does" -- and making that a function-name and moving the code block into the function.

Usually, I'm refactoring to get commonalities out of a code segment so I can reduce code size and have several places use the same code -- in which case, the 'sub' is usually outside of the sub I'm in. But sometimes, I'm simply refactoring because I'm "digesting"...trying to break the code down into smaller more portable bites or pieces, that I can more easily glance at and tell if they are working or not and easily understand them. It could be similar to going through my writing and trying to eliminate the wordiness (I tend toward overwordiness, though I'm sure no one has noticed; :-)) or break apart larger sentences into smaller ones. Occasionally, I can run into a the equivalent of a run-on sentence that takes up an entire paragraph that would be more clear if broken up. If its code I have some time to clean up, I'm usually much happier with it and I'm more likely to be able to pick it up and work with it again in 6-12 months time -- vs. "stream-of-consciousness" blitz filters or scripts to do a task that I want or need to get done.

It's like when I'm thinking about the task or work that needs to be done, it's hard to think about how to also make the instructions of how to do that crystal clear to a third party -- they are different foci, which is why I usually like to work in "passes" -- getting something working so I can begin 'testing' my grasp about what I'm doing... Writing the program is a great way to really flesh out a problem -- since it has to be clearly explained at least well enough that the computer can understand what you meant. Converting that to a readable form makes it into a releasable program.

Does that make sense?

Replies are listed 'Best First'.
Re^3: Perl scoping not logical...?
by jettero (Monsignor) on Apr 28, 2008 at 11:16 UTC

    Does that make sense?

    Not really.

    I certainly don't want the routine *compiled* each time I invoke the routine. I want it to use the same lexical frame as the variables that the sub is defined in.

    You can either pass them in to the sub, or you can use lambdas. In perl, today, you can't have it both ways. Even if you had named lexical subs, they'd still have to be recompiled each time (minus compiler optimizations, which may exist for function ref lambdas). Anyway, I think function refs are perfectly clear. They're very widely used and when you need a lambda, they're the appropriate way to do it.

    Here's just a couple of the common uses. You can think of millions more I'm sure. Don't shy away from function refs. They're quite clear.

    my $awesome = awesome(); print "still tickin'\n" while $awesome->(); sub awesome { my @a = (1 .. 10); return sub { shift @a }; } my %code_table = ( action1 => sub {print "doin' it\n"}, ); $code_table{action1}->(); # also awesome

    People really expect the subs to work they way they do now though, so it's not likely to be changed until perl6 at the earliest. Imagine how much code would break if they suddenly worked differently?

    The locals aren't really being crushed...their just in flux....(duplicated, really)....

    Oh, I get it. I'm just saying that...

    my ($c,$d); my ($c,d) = (4,5); # ...maybe we can live without the fi +rst my?

    Essentially, I was asking if that was unintentional and might be causing your troubles.

    -Paul

      People really expect the subs to work they way they do now though, so it's not likely to be changed until perl6 at the earliest. Imagine how much code would break if they suddenly worked differently?
      I don't believe I am suggesting that existing "subs" work differently. What I proposed was the ability to declare a sub with "my" just as one does with variables. Do you think that if people saw:
      sub print_sum($$) { my ($x, $y) =@_; my sub adder {return $_[0]+$_[1] }; printf "sum of $x, $y = %d\n", adder($x, $y); }
      That people would get confused about why "adder" would be used as a helper function to the main sub "print_sum"?

      Is there another possible meaning of "my sub" that would be confused with using it to specify that sub is local to the block just like the variables are?

      I'm not entirely clear about the term 'lambda'. Something to do with anonymous functions in lisp? I don't recall seeing it in the perl docs I've read (doesn't me an it's not there...just don't recall it! :-)).

        You are far from the first to want lexical subroutines. There's a source-filter using proof-of-concept in Sub::Lexical. I don't recall there being any objection to actually implementing them in perl5 - it just hasn't happened to date (and may never, since it would be a lot of work and offer limited benefit over just using a lexical coderef).