Click to See Complete Forum and Search --> : perl: determining context of sub
YaRness
01-23-2001, 03:45 PM
i read a bunch of function in the man pages that say "if it's in a list context, returns a list, otherwise returns blah blah blah". i know this means that given sub foo i can do
@list = foo;
or
if (foo)
etc.
what i wanna know is, when you are coding a sub, how do yo determine whether it was called in a list context or a single scalar context?
------------------
"Assembly of Japanese bicycle require great peace of mind."
Registered Linux User #188285 http://counter.li.org/
WHich functions are you referring to. Perhaps you should be a bit more specific that "blah blah blah". http://www.linuxnewbie.org/ubb/biggrin.gif
TheLinuxDuck
01-23-2001, 05:18 PM
Originally posted by YaRness:
what i wanna know is, when you are coding a sub, how do yo determine whether it was called in a list context or a single scalar context?
I don't think there is a difference. Consider the way to assign specific variable names to data passed into a sub.
sub myWeirdSub
{
my($jimPath)=@_;
..
}
# or
sub myWeirdSub
{
my(@jimPaths)=@_;
..
}
In the first example, the list is being passed to a scalar. Perl automatically dumps the first item of the array into the scalar. Since it's being passed to a scalar, the rest of the data in the array is left alone.
In the second example, the list is passed completely into the array, duplicating it. Both calls are exactly the same. The only thing that changes anything is the variable type being used as the buffer.
When you output, the sub will react the same no matter:
sub myWeirdSub
#!/usr/bin/perl -w
use strict;
my(@data)=qw(/to/here /to/there);
if(myWeirdSub(@data)) {
# didn't return an undef
print "Not undef\n";
my($single)=myWeirdSub(@data);
my(@leftOver)=myWeirdSub(@data);
print "\$single: $single\n\@leftOver: @leftOver\n";
}
else {
print "Nothing returned from sub\n";
}
sub myWeirdSub
{
my(@jimsPaths)=@_;
shift @jimsPaths and shift @jimsPaths if($#jimsPaths>0);
# we simply remove two items from the list, if more than 1 exists
return @jimsPaths;
}
Now, if only two items are passed into this sub, it will return an undef:
/home/root/perl/yar> ./passing.pl
Nothing returned from sub
But, if we change the @data to three items:
my(@data)=qw(/to/here /to/there /to/everywhere);
we get:
/home/root/perl/yar> ./passing.pl
Not undef
$single: /to/everywhere
@leftOver: /to/everywhere
Add another, and $single remains the same, but @leftOver will continue to grow based on how many weren't slurped from the array.
The sub shouldn't care, from my understanding, what is being done with it, as long as it receives the data it expects to receive. The user of the sub can deal with the return as he/she sees fit.
Or has fits... http://www.linuxnewbie.org/ubb/biggrin.gif
------------------
TheLinuxDuck
I have a belly button.
:wq
jemfinch
01-23-2001, 06:59 PM
Whether a sub is called in list context or scalar context doesn't have anything to do with the way the arguments are passed to it; it has everything to do with the variables its return value is being assigned to.
@array = myfunc(foo);
is calling myfunc in array context, and
$scalar = myfunc(foo);
is calling myfunc in scalar context.
(now, for the obligatory, "this is just one more perl ugliness that led me to python" remark http://www.linuxnewbie.org/ubb/smile.gif)
Jeremy
TheLinuxDuck
01-23-2001, 07:33 PM
Originally posted by jemfinch:
Whether a sub is called in list context or scalar context doesn't have anything to do with the way the arguments are passed to it; it has everything to do with the variables its return value is being assigned to.
My point is not that passed parameters and return values have anything to do with each other. It is obvious that they don't. My point is that the lvalue determines what context it is called in.
I was using a familiar point of reference, since many people use
# vars only samples for reference
my($firstParam,$arrayRef,@array)=@_;
inside of a sub to give the passed parameters familiar/easy-to-use names. The array @_ doesn't care how it is accessed. The lvalue is what makes the difference.
Since I knew that YaR knew this, I felt I didn't need to point it out. I guess I should have been more clear for others.
------------------
TheLinuxDuck
I have a belly button.
:wq
klamath
01-23-2001, 07:34 PM
Take a look at wantarray - I believe that's what you're looking for.
------------------
- Klamath
Get my GnuPG Key Here (http://klamath.dyndns.org/mykey.asc)
Looking for an open source project to contribute to? Check out the Tornado HTTP Server (http://sourceforge.net/projects/tornado)
TheLinuxDuck
01-23-2001, 07:51 PM
The sub shouldn't care, from my understanding, what is being done with it, as long as it receives the data it expects to receive. The user of the sub can deal with the return as he/she sees fit.
jemfinch: If this is what you're refering to, my point is that inside the sub, it doesn't care what goes on outside of the sub. All it knows is that it has certain requirements (some anyway) of specific CL parameters. Once it gets the CL parameters, it deals with them accordingly, then passes the information out the way it was told to pass it.
After that, the sub doesn't care what happens. The coder can dump the return value into lala land for all it knows.. it's all in the lvalue.
Just thought I should explain that better.
------------------
TheLinuxDuck
I have a belly button.
:wq
[This message has been edited by TheLinuxDuck (edited 23 January 2001).]
YaRness
01-23-2001, 08:43 PM
Originally posted by klamath:
Take a look at wantarray - I believe that's what you're looking for.
that sounds right and familiar. jemfinch also nailed what i was askin about, sorry if i wasn't clear.
(hey jemfinch, when you find something you like better than python, will you start bad-mouthing it all the time like you do perl? i ran across an old post where you were defending perl tooth-and-nail http://www.linuxnewbie.org/ubb/wink.gif (some topic about best programming language or some such, from aug-sept about) )
------------------
"Assembly of Japanese bicycle require great peace of mind."
Registered Linux User #188285 http://counter.li.org/
TheLinuxDuck
01-24-2001, 02:44 AM
jemfinch:
I'm sorry if I sounded insulting to you in my posts. I have been thinking about what I said, and I think that I was harsh and unnecessarily rude to you, and for that I am sorry.
That's what happens when I think I know something that I most certainly am not an expert on.. http://www.linuxnewbie.org/ubb/smile.gif I put my foot in my mouth and chew.
I hope you'll accept my apology. My brashness was certainly uncalled for.
------------------
TheLinuxDuck
I have a belly button.
:wq
jemfinch
01-24-2001, 03:12 AM
Originally posted by YaRness:
(hey jemfinch, when you find something you like better than python, will you start bad-mouthing it all the time like you do perl? i ran across an old post where you were defending perl tooth-and-nail http://www.linuxnewbie.org/ubb/wink.gif (some topic about best programming language or some such, from aug-sept about) )
Probably. But only those parts that the new language does better than python.
I'm an advocate. I always will be -- whatever I like at the moment, I advertise and advocate as the best thing in the world. It's just the way I am.
i ran across an old post where you were defending perl tooth-and-nail
Can you toss a link up here? I'm curious what crazy things I'd say in my days when I was drunk on perl. http://www.linuxnewbie.org/ubb/smile.gif
Originally posted by TheLinuxDuck:
I'm sorry if I sounded insulting to you in my posts. I have been thinking about what I said, and I think that I was harsh and unnecessarily rude to you, and for that I am sorry.
Oh, don't worry about it. I expect it after consistently following my comments about perl with, "this is something python does better than perl" in threads that don't even care about python. I'm used to it after all my advocacy.
But maybe someone will try python one day and feel the same way I do, and then all my work will have gone to good use http://www.linuxnewbie.org/ubb/smile.gif
Jeremy
P.S. The one thing perl does better than python is conciseness. When I need a quick filter or something, I'm far more likely to write a command line perl -pi -e 's/foo/bar/' than I am to write a complete python script. One of my personal favorites is to do this with bash for loops:
for file in *.bmp
do
convert $file `echo $file | perl -pe 's/(?:^mim_-?\d+_.)|(?:.bmp$)//g'`.png
done
:-D
YaRness
01-24-2001, 09:39 AM
jemfinch: i have no problem with aggressive advocacy, as long as you are able to admit to it http://www.linuxnewbie.org/ubb/biggrin.gif although suggesting a python answer when someone asks for perl specifically is a bit irritating. but i gotta hand it to you, you still answer the perl questions good nuff when you do, even if you choke over it http://www.linuxnewbie.org/ubb/biggrin.gif
umm, lemme see if i can find that post again...
here we go: http://www.linuxnewbie.org/ubb/Forum14/HTML/001085.html
and a quote from it:
jemfinch
I can't think of anything tedious in Perl.
now if that isn't funny, then i don't know funny.
------------------
"Assembly of Japanese bicycle require great peace of mind."
Registered Linux User #188285 http://counter.li.org/
jemfinch
01-25-2001, 07:22 AM
Ah, YaRness, you missed the best part of that post!
Sweede: Is Perl OO?
jemfinch: Mine sure as hell isn't.
That's <ahem> a bit of a change from my current manner, I'd say http://www.linuxnewbie.org/ubb/smile.gif
Of course, it also explains why at that point I didn't think anything in perl was tedious.
I seemed to have a lot of anger in that thread. Hmm...september...I was probably upset because all my friends had gone off to college while I, the temporary college dropout (transfer troubles which are now resolved) was stuck at home bussing tables. You should've seen the portsentry thread in the security forum around that time http://www.linuxnewbie.org/ubb/smile.gif
Jeremy
YaRness
01-25-2001, 09:37 AM
eh. stuff happens.
OO in perl is just (at the moment) kinda fluff to make all the people that want to do EVERYTHING in perl happy (which it really wasn't intended for i don't think). i spent all day playing with OO stuff, then realized for short stuff, it's just a waste of overhead (of course that applies to a lot of languages, but especially when you are just interpreting and not compiling binaries i think).
------------------
"Assembly of Japanese bicycle require great peace of mind."
Registered Linux User #188285 http://counter.li.org/
YaRness
01-26-2001, 02:22 PM
Originally posted by klamath:
Take a look at wantarray - I believe that's what you're looking for.
also just realized this is how you figure out if a subroutine should return it's value to $_. from the man pages:
Returns true if the context of the currently executing subroutine is looking for a
list value. Returns false if the context is looking for a scalar. Returns the
undefined value if the context is looking for no value (void context).
so if (wantarray == undef) {$_ = $output;}
------------------
"Assembly of Japanese bicycle require great peace of mind."
Registered Linux User #188285 http://counter.li.org/
TheLinuxDuck
01-26-2001, 05:47 PM
Originally posted by YaRness:
so if (wantarray == undef) {$_ = $output;}
Hmm.. I don't think I fully understand that.. ok, I never even saw this before.. I just looked in 'pp3rd' and found it . http://www.linuxnewbie.org/ubb/smile.gif
Their example is:
return unless defined wantarray;
my (@a)=complex_calculation();
return wantarray?@a:\@a;
Qool! http://www.linuxnewbie.org/ubb/smile.gif
------------------
TheLinuxDuck
I have a belly button.
:wq
YaRness
01-26-2001, 10:54 PM
it's like this.
#here's what you might have at the end
#of a subroutine
#
#first off, if wantarray is undefined,
#the other stuff won't work. also means
#the sub was called in a void context
if (defined wantarray)
{
#if it's equal to one, it was called in
#an array context, ie, @list = sub()
if (wantarray)
{
return @list;
}
#otherwise it's 0, so sub was called
#like $scalar = sub()
else
{
return $scalar;
}
}
#if wantarray is undef, then we are in a void
#context, so we set $_ equal to something
$_ = $something;
so
@mylist = sub(); #would get @list in the above snippet
$string = sub(); #would get $scalar
sub(); #$_ would get $something
hope that makes it clearer than mud.
------------------
"Assembly of Japanese bicycle require great peace of mind."
Registered Linux User #188285 http://counter.li.org/