Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Trying to understand the SHIFT function and Lexical Variables ? 3

Status
Not open for further replies.

garymgordon

Programmer
Apr 5, 2000
307
US
I am seeing a piece of code - in the creation of a small Perl module as follows:


package Circle;
1;

sub circumference
{
$d = shift;
return 3.14 * $d;
}

sub area
$r = shift;
return 3.14 * $r * $r;
}



Then, the perl file is as follows:


#!/usr/bin/perl

require Circle;

print ("Circumference = ");
print Circle::circumference(10), "\n";

print ("Area = ");
print Circle::area(5), "\n";




My questions regarding the above package is:

1) What is SHIFT doing in the above situation? It said something in my book such as : Subroutines often start by copying their arguments into lexical variables, and shift can be used for this.

In the circumference example, ... if 10 is being passed into the subroutine 'circumference' ... how is it being assigned to the $d variable?

I don't fully understand what is happening or what they mean.

2) What exactly are LEXICAL Variables ... and LEXICAL Scope???

3) Does every Module need to start out with 1; ? And if not, why not ... and what are my options?

Thanks,
Gary
Gary M. Gordon, LLC
webmaster@garymgordon.com
Certified Web Developer ::
Application Programmer
 
Just lazy coding really, easy to write but it's not obvious - to those not familiar with the idiom - what's going on:

sub circumference
{
[tab]$d = shift;
[tab]return 3.14 * $d;
}

is equivalent to

sub circumference($)
{ my ($diameter) = @_;[tab][tab]# get the parameter
[tab]return 3.14 * $diameter;
}

and you would call the circumference function like this:

my $circ = circumference(12); # 12 is the diameter of th circle
Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
Mike,

1) I didn't understand the $ in the () ??

2) What and how is SHIFT functioning (as displayed in my original coding)? What is it? What is it doing? Please explain the use of shift in this manner?

3) In :

sub circumference($)
{ my ($diameter) = @_; # get the parameter
return 3.14 * $diameter;
}


Could @_ been written as $_[0] ???
I am just trying to understand this.

And was the use of $ in the () simply to return TRUE? But please explain what the $ is doing ??

Thanks,
Gary
Gary M. Gordon, LLC
webmaster@garymgordon.com
Certified Web Developer ::
Application Programmer
 
The $ in the () is just a way of telling the perl compiler that the parameter to the function is a single scalar variable. It's called a "prototype". It's not really required.

What the shift does is remove and return the FIRST element of a list. When no list is specified the default is the list @_, which is the list of parameters passed to a function.

Yes, in this case the @_ could have been written was $_[0]. I like using the @_ array instead because, if your function requires more than one parameter, you can do this:
Code:
my($param1, $param2, $param3) = @_;
This is a clean, neat way to assign all your parameters names which are lexically scoped to the function in a single statement.
Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard.
 
"It's called a "prototype". It's not really required."

tut tut tsdragon.... they can throw you out of the programmers guild for talking like that you know.... :)

You're quite right though -- it will work without it. The advantage of using ($) in a function definition is that if you try and call that function without any parameters, or with more than one (the number of $'s in the brackets), you will get a compile time error. So it's a nice error checking thing, and will catch quite a few typing errors.
Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
If prototyping worked better in perl, I'd use it. But it's not that good yet. It doesn't work at all with &sub-style calls, subroutine references or indirect subroutine calls. Also it can force implied references to passed parameters without the knowledge of the person calling the subroutine and it can force a context which the caller may not be aware of. Not that I think there's anything wrong with it, just that you have to be careful with it, and it can be limiting and/or confusing in places where it doesn't need to be. Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard.
 
For questions on functions in Perl, try

perldoc -f shift

This usually gives a pretty good explanation.

Disclaimer:
Beware: Studies have shown that research causes cancer in lab rats.
 
"it can force implied references to passed parameters"

<surprised> ..... it can? Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
From the perlsub man page:
&quot;Any backslashed prototype character represents an actual argument that absolutely must start with that character. The value passed as part of @_ will be a reference to the actual argument given in the subroutine call, obtained by applying \ to that argument.&quot;

Since perl applies the \ to the argument, I'd call that an implied reference, wouldn't you?
Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard.
 
tsdragon,

I apologize, but I have no idea what you meant by the last comment. Would you mind explaining how and what this has to do with my question. hahaha Sorry. My brain must be fried or something, but I don't understand.

Gary
Gary M. Gordon, LLC
webmaster@garymgordon.com
Certified Web Developer ::
Application Programmer
 
It doesn't have anything to do with your question. It was a response to MikeLacey's question about my comment that using prototypes can force implied references to passed parameters. If you put a backslash in front of a prototype character perl pass the subroutine a reference to the actual parameter. Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard.
 
Well ... that makes me feel better. hahaha

Thanks for explaining.

Gary
Gary M. Gordon, LLC
webmaster@garymgordon.com
Certified Web Developer ::
Application Programmer
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top