Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Pass by reference question

Reply
Thread Tools

Pass by reference question

 
 
grocery_stocker
Guest
Posts: n/a
 
      08-13-2007
If perl can pass stuff by reference, then why do you have to deference
it. Like for example

@tailings = popmany ( \@a, \@b, \@c, \@d );


sub popmany {
my $aref;
my @retlist = ();
foreach $aref ( @_ ) {
push @retlist, pop @$aref;
}
return @retlist;
}


Wouldn't it be more accurate to say that perl passes the reference by
value? I just find this sort of odd because in both Java (withc uses
pass the reference by value) and C++ (which supports pass by
reference), I never recall having to dereference a reference like what
I have to in perl.

 
Reply With Quote
 
 
 
 
grocery_stocker
Guest
Posts: n/a
 
      08-13-2007
On Aug 12, 7:34 pm, Sherm Pendley <(E-Mail Removed)> wrote:
> grocery_stocker <(E-Mail Removed)> writes:
> > Wouldn't it be more accurate to say that perl passes the reference by
> > value?

>
> Yes. So why did you say it passes by reference, when you already know a
> more accurate way of saying it?
>


Because too my knowledge, ALL the perldocs and perl books say perl
just passes the reference. I couldn't find anything in the perldocs
that would hint that perl uses 'pass the reference by value'.


 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      08-13-2007
grocery_stocker <(E-Mail Removed)> wrote:
> If perl can pass stuff by reference, then why do you have to deference
> it.


No, you can't. Perl only allows to pass scalars to functions and
those are passed by value. The only thing that's a bit special
in Perl is that if you e.g. have an argument that is an array it
automatically gets converted into a list of scalars and the values
of these scalars get passed to the subroutine. (Other languages
have similar ways that may look strange at a first glance, e.g.
in C and C++ if you use an array as the argument of a function
it automatically gets converted into a pointer to the first
element of the array and this value is passed to the function.)

> Like for example


> @tailings = popmany ( \@a, \@b, \@c, \@d );


Sorry, but here you pass scalars to Perl whose values are
references. This is not the same as "passing by reference".
"Passing by reference" means that an argument automatically
gets converted to a reference and that within the subroutine
receiving it in all places the argument is also automatically
dereferenced without you having to spell it out explicitely.

Compare the these two C++ functions: that do the same thing:

void foo_by_val( int* i ) {
*i = 3;
}

void foo_by_ref( int& i ) {
i = 3;
}

The first one you would have to call as

int x;
foo_by_val( &x );

and the second as

foo_by_ref( x );

Perl only has an equivalent for the foo_by_val() function but
not for foo_by_val().

> sub popmany {
> my $aref;
> my @retlist = ();
> foreach $aref ( @_ ) {
> push @retlist, pop @$aref;
> }
> return @retlist;
> }


> Wouldn't it be more accurate to say that perl passes the reference by
> value?


It's redundant since Perl only passes by value. A reference is
nothing than a scalar (basically what you would call a pointer
in C or C++) and scalars, the only things you can pass to sub-
routines, are always passed by values.

> I just find this sort of odd because in both Java (withc uses
> pass the reference by value) and C++ (which supports pass by
> reference), I never recall having to dereference a reference like what
> I have to in perl.


You have to because Perl (like e.g. C but unlike Java or C++)
simply doesn't do "pass by reference", just "pass by value".

Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Josef Moellers
Guest
Posts: n/a
 
      08-13-2007
Jens Thoms Toerring wrote:
> grocery_stocker <(E-Mail Removed)> wrote:
>
>>If perl can pass stuff by reference, then why do you have to deference
>>it.

>
>
> No, you can't. Perl only allows to pass scalars to functions and
> those are passed by value.


Why, then, does the following script print "Bar"?

sub f($) {
$_[0] = 'Bar';
}
my $v = 'Foo';
f($v);
print "$v\n";

Josef
--
These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://www.fujitsu-siemens.com/imprint.html

 
Reply With Quote
 
Josef Moellers
Guest
Posts: n/a
 
      08-13-2007
Jens Thoms Toerring wrote:
> grocery_stocker <(E-Mail Removed)> wrote:
>
>>If perl can pass stuff by reference, then why do you have to deference
>>it.

>
>
> No, you can't. Perl only allows to pass scalars to functions and
> those are passed by value.


Why, then, does the following script print "Bar"?

sub f($) {
$_[0] = 'Bar';
}
my $v = 'Foo';
f($v);
print "$v\n";

And what does this script's error message tell us?

sub f($) {
$_[0] = 'Bar';
}
f('Foo');

With all due respect,

Josef
--
These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://www.fujitsu-siemens.com/imprint.html

 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      08-13-2007
grocery_stocker <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> If perl can pass stuff by reference, then why do you have to deference
> it. Like for example
>
> @tailings = popmany ( \@a, \@b, \@c, \@d );
>
>
> sub popmany {
> my $aref;
> my @retlist = ();
> foreach $aref ( @_ ) {
> push @retlist, pop @$aref;
> }
> return @retlist;
> }
>
>
> Wouldn't it be more accurate to say that perl passes the reference by
> value? I just find this sort of odd because in both Java (withc uses
> pass the reference by value) and C++ (which supports pass by
> reference), I never recall having to dereference a reference like what
> I have to in perl.


The perceived problem here is mostly due to ambiguous terminology.

There is the common distinction of parameter passing "by value" vs "by
reference". The first one means that all a subroutine ever gets to see
is a copy of the parameter value whereas the second means the subroutine
has access to the variable as it exists in the caller's context and can,
for instance, change the value so that the change is visible to the
caller.

Perl subs implement "pass by reference" in this sense, since assigning
to elements of @_ changes the value for the caller. This description
went into the Perl documentation, and when Perl was young (before Perl
5) this caused no problems because the term "reference" didn't have
a Perl-specific meaning back then.

That changed when Perl 5 introduced its own references (what you get
by prefixing a variable with a backslash). These references are *not*
what Perl uses to implement its "pass by reference", but an entirely
distinct notion. In Perl terms, what is commonly called "pass by
reference" might be called "pass by alias(ing)", but that term is not
in general use and wouldn't be readily understood. So the documentation
continues to use the commonly recognized term even after it has become
ambiguous.

Anno
 
Reply With Quote
 
Josef Moellers
Guest
Posts: n/a
 
      08-13-2007
grocery_stocker wrote:
> If perl can pass stuff by reference, then why do you have to deference
> it. Like for example
>
> @tailings = popmany ( \@a, \@b, \@c, \@d );
>
>
> sub popmany {
> my $aref;
> my @retlist = ();
> foreach $aref ( @_ ) {
> push @retlist, pop @$aref;
> }
> return @retlist;
> }
>
>
> Wouldn't it be more accurate to say that perl passes the reference by
> value? I just find this sort of odd because in both Java (withc uses
> pass the reference by value) and C++ (which supports pass by
> reference), I never recall having to dereference a reference like what
> I have to in perl.
>


Perl passes variables by reference and dereferences them automagically.
If you explicitly pass a reference ('\@a'), you'll have to dereference
it explicitly.
I.e. in your example, popmany is passed four references to references to
arrays.

Josef
--
These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://www.fujitsu-siemens.com/imprint.html

 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      08-13-2007
Josef Moellers <(E-Mail Removed)> wrote:
> Jens Thoms Toerring wrote:
> > grocery_stocker <(E-Mail Removed)> wrote:
> >
> >>If perl can pass stuff by reference, then why do you have to deference
> >>it.

> >
> > No, you can't. Perl only allows to pass scalars to functions and
> > those are passed by value.


> Why, then, does the following script print "Bar"?


> sub f($) {
> $_[0] = 'Bar';
> }
> my $v = 'Foo';
> f($v);
> print "$v\n";


> And what does this script's error message tell us?


> sub f($) {
> $_[0] = 'Bar';
> }
> f('Foo');


It tells me that I obviously I was writing BS, at least when I
didn't mention that using prototypes changes the picture.

Ok, to the OP: you could write your function e.g. as

sub popmany(\@;\@;\@;\@) {
return map { pop @$_ } @_;
}

and then call it as

@tailings = popmany @a, @b, @c, @d;

using the possibility to "pass by reference" when using prototypes.
But please note that this only will work with up to four arrays,
so the function would be better named pop_up_to_four() or something
like that.

But my personal preference is to avoid prototypes except for the
very purpose they were introduced for, mimiking the behaviour of
built-in functions like push or pop. You still have to use the
dereference syntax for arrays and hashes within the subroutine
since what arrives within the subroutine are still scalars. And
be wary of modifying elements of @_ unless you understand fully
what to expect (I find it a bit weird). And, finally, prototypes
don't influence method calls, only "normal" functions.

At least don't assume that prototypes play a similar role to
those in other languages like C, C++, Java etc., they don't.
They aren't meant for compile time type checking.

Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      08-13-2007
grocery_stocker <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> If perl can pass stuff by reference, then why do you have to deference
> it. Like for example
>
> @tailings = popmany ( \@a, \@b, \@c, \@d );
>
>
> sub popmany {
> my $aref;
> my @retlist = ();
> foreach $aref ( @_ ) {
> push @retlist, pop @$aref;
> }
> return @retlist;
> }


On an unrelated note (unrelated to the question, that is), popmany()
can be written more compact as

sub popmany { map pop @$_, @_ }

Anno
 
Reply With Quote
 
xhoster@gmail.com
Guest
Posts: n/a
 
      08-13-2007
grocery_stocker <(E-Mail Removed)> wrote:
> If perl can pass stuff by reference, then why do you have to deference
> it. Like for example
>
> @tailings = popmany ( \@a, \@b, \@c, \@d );


You are sticking the backwhacks in front of those arrays, not Perl.
(If you are using prototypes, then perl will in effect add the backwhacks
for you, but that is a different matter).

Since you took the reference, not Perl, then you have to do the
dereference.



>
> sub popmany {
> my $aref;
> my @retlist = ();
> foreach $aref ( @_ ) {
> push @retlist, pop @$aref;
> }
> return @retlist;
> }
>
> Wouldn't it be more accurate to say that perl passes the reference by
> value? I just find this sort of odd because in both Java (withc uses
> pass the reference by value) and C++ (which supports pass by
> reference), I never recall having to dereference a reference like what
> I have to in perl.


Perl does "pass the thingamabob by alias". That that thingamabob which was
passed by alias is a reference is due to your particulars and Perl's
generals.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
difference between pass by address and pass by reference!! blufox C Programming 2 04-03-2006 02:53 PM
pass by reference vs pass by pointer LuB C++ 6 09-23-2005 06:19 AM
Pass by reference / pass by value Jerry Java 20 09-09-2005 06:08 PM
Pass by Pointer * or Pass by Reference &? Robert C++ 10 08-24-2005 04:15 PM
Pass-by-reference instead of pass-by-pointer = a bad idea? Mr A C++ 111 07-14-2005 03:04 AM



Advertisments