pass by reference

L

Larry

The following code snippet shows how I do "pass by reference" in
Perl. It works fine, but I'm wondering... is there a less verbose way
to do this?

(I know in this simple example, I could avoid the typeglob assignment
and just use $$arg instead of $arg, but in a more complex usage, that
would bug me... I'd rather just use the more normal-looking $arg
everywhere.)

-------------

sub squareMe (\$) {
my ($argRef) = @_;
local *arg = $argRef;
our $arg;

$arg *= $arg;
}

my $n = 7;
squareMe $n;
print "$n\n"; # prints 49
 
B

Billy Patton

Larry said:
The following code snippet shows how I do "pass by reference" in
Perl. It works fine, but I'm wondering... is there a less verbose way
to do this?

(I know in this simple example, I could avoid the typeglob assignment
and just use $$arg instead of $arg, but in a more complex usage, that
would bug me... I'd rather just use the more normal-looking $arg
everywhere.)

-------------

sub squareMe (\$) {
my ($argRef) = @_;
local *arg = $argRef;
our $arg;

$arg *= $arg;
}

my $n = 7;
squareMe $n;
print "$n\n"; # prints 49

Do you really want side effects ?
Passing by reference does this.
Guess this is too simple to make that decision.

sub squareMe($) {
my ($arg) = @_;
$arg *= $arg;
}

my $n=7;
$n = squareMe $n; # no side effects
I hate it when my variables get changed somewhere else and I have to
track it down for debugging!
 
P

Peter Makholm

Larry said:
The following code snippet shows how I do "pass by reference" in
Perl. It works fine, but I'm wondering... is there a less verbose way
to do this?

Perl already implements a kind of pass by reference in the @_
argument.

#!/usr/bin/perl -l
sub squareMe {
$_[0] *= $_[0];
}

my $n = 7;
squareMe $n;
print $n; # Does indeed print 49

__END__
(I know in this simple example, I could avoid the typeglob assignment
and just use $$arg instead of $arg, but in a more complex usage, that
would bug me... I'd rather just use the more normal-looking $arg
everywhere.)

No, using pass by reference isn't the normal case, so hiding it will
only make you code more obscure and less maintainable when you forget
whatever samrtness you have put into the code.

Pass by reference can be useful, but keep it well documented and let
it stand out.

//Makholm
 
L

Larry

Larry said:
The following code snippet shows how I do "pass by reference" in
Perl. It works fine, but I'm wondering... is there a less verbose way
to do this?

Perl already implements a kind of pass by reference in the @_
argument.

#!/usr/bin/perl -l
sub squareMe {
$_[0] *= $_[0];

}

my $n = 7;
squareMe $n;
print $n; # Does indeed print 49

__END__
(I know in this simple example, I could avoid the typeglob assignment
and just use $$arg instead of $arg, but in a more complex usage, that
would bug me... I'd rather just use the more normal-looking $arg
everywhere.)

No, using pass by reference isn't the normal case, so hiding it will
only make you code more obscure and less maintainable when you forget
whatever samrtness you have put into the code.

Pass by reference can be useful, but keep it well documented and let
it stand out.

//Makholm

I don't like the $_[0] method, because it doesn't give me a chance to
name my variables.... I prefer names, not numbers, thank you! :)
 
P

Paul Lalli

I don't like the $_[0] method, because it doesn't give me a
chance to name my variables.... I prefer names, not numbers,
thank you!

So use your name the entire time you're actually doing something with
the variable, then change it back at the end:

$ perl -le'
my $x = 7;
squareMe($x);
print $x;

sub squareMe {
my ($arg) = @_;
$arg **= 2;
$_[0] = $arg;
}
'
49


Paul Lalli
 
U

Uri Guttman

L> I don't like the $_[0] method, because it doesn't give me a chance to
L> name my variables.... I prefer names, not numbers, thank you! :)

so pass in a reference. the typeglob hack you created is fugly and
wasteful. and don't use prototypes as they are not what you want here. a
plain simple reference works fine.

uri
 
L

Larry

L> I don't like the $_[0] method, because it doesn't give me a chance to
L> name my variables.... I prefer names, not numbers, thank you! :)

so pass in a reference. the typeglob hack you created is fugly and
wasteful. and don't use prototypes as they are not what you want here. a
plain simple reference works fine.

I don't want to pass in a reference! You call that "passing by
reference"?! :)

I want to write:

squareMe $foo

not

squareMe \$foo

!!!
 
L

Larry

L> I don't like the $_[0] method, because it doesn't give me a chance to
L> name my variables.... I prefer names, not numbers, thank you! :)
so pass in a reference. the typeglob hack you created is fugly and
wasteful. and don't use prototypes as they are not what you want here. a
plain simple reference works fine.

I don't want to pass in a reference! You call that "passing by
reference"?! :)

I want to write:

squareMe $foo

not

squareMe \$foo

!!!

And I *do* need the prototypes... that's the only way to get the
reference without my callers having to use backslashes!
 
L

Larry

The following code snippet shows how I do "pass by reference" in
Perl. It works fine, but I'm wondering... is there a less verbose way
to do this?

(I know in this simple example, I could avoid the typeglob assignment
and just use $$arg instead of $arg, but in a more complex usage, that
would bug me... I'd rather just use the more normal-looking $arg
everywhere.)

-------------

sub squareMe (\$) {
my ($argRef) = @_;
local *arg = $argRef;
our $arg;

$arg *= $arg;

}

my $n = 7;
squareMe $n;
print "$n\n"; # prints 49

I just figured out a somewhat more elegant way:

sub squareMe (\$) {
local (*arg) = @_;
our $arg;

$arg *= $arg;

}

Too bad about the need for having to repeat "arg" in "our" though...
 
L

Larry

Do you really want side effects ?
Passing by reference does this.
Guess this is too simple to make that decision.

sub squareMe($) {
my ($arg) = @_;
$arg *= $arg;

}

my $n=7;
$n = squareMe $n; # no side effects
I hate it when my variables get changed somewhere else and I have to
track it down for debugging!

Sometimes, I do want side effects! What if I know that every time I
call "squareMe" I will want to modify the var. being squared?

I'd rather write:

squareMe $n

than

$n = squareMe $n
 
U

Uri Guttman

L> I don't like the $_[0] method, because it doesn't give me a chance to
L> name my variables.... I prefer names, not numbers, thank you! :)
L> I don't want to pass in a reference! You call that "passing by
L> reference"?! :)

sure is but it is just explicit. i know what pass by ref is.

L> I want to write:

L> squareMe $foo

L> not

L> squareMe \$foo

well, then use $_[0] as others have said. your typeglob answer is
horrible for such a simple issue. in my view you are working too hard
for a tiny syntactical gain. this is from a few weeks of coding
experience that i have :)

uri
 
U

Uri Guttman

"L" == Larry <[email protected]> writes:
L> I don't like the $_[0] method, because it doesn't give me a chance to
L> name my variables.... I prefer names, not numbers, thank you! :)
so pass in a reference. the typeglob hack you created is fugly and
wasteful. and don't use prototypes as they are not what you want here. a
plain simple reference works fine.

I don't want to pass in a reference! You call that "passing by
reference"?! :)

I want to write:

squareMe $foo

not

squareMe \$foo

!!!

L> And I *do* need the prototypes... that's the only way to get the
L> reference without my callers having to use backslashes!

nope again. they can get a ref earlier into another scalar and pass
that. your api design to make their life 'easier' is actually making it
harder. but do what you want.

uri
 
U

Uri Guttman

L> I just figured out a somewhat more elegant way:

L> sub squareMe (\$) {
L> local (*arg) = @_;
L> our $arg;

L> $arg *= $arg;

L> }

ewwwwww!

L> Too bad about the need for having to repeat "arg" in "our" though...

double ewwwwww.

tell them to pass a real ref and be done with it. they need to learn
about refs anyhow and coddling your callers is doing them a big
disservice.

uri
 
L

Larry

tell them to pass a real ref and be done with it. they need to learn
about refs anyhow and coddling your callers is doing them a big
disservice.

uri

I see your point, but I miss "real" passing by reference from Pascal
and Ada. But C, Perl and Java seem to want to bury it :(
 
L

Larry

I see your point, but I miss "real" passing by reference from Pascal
and Ada. But C, Perl and Java seem to want to bury it :(

And put C++ in with Pascal and Ada!
 
M

Mumia W.

I don't like the $_[0] method, because it doesn't give me a chance to
name my variables.... I prefer names, not numbers, thank you! :)

No problem. Just use typeglob aliases:

use strict;
use warnings;
our $argument;

$argument = 4;
squareMe($argument);
print $argument, "\n";

sub squareMe {
local *argument = \$_[0];
$argument *= $argument;
}
 
J

J. Gleixner

Larry said:
Sometimes, I do want side effects! What if I know that every time I
call "squareMe" I will want to modify the var. being squared?

Fine. Everyone is telling you that it's not a good practice
and you're not going to convince anyone that it is a good practice.

As long as you are the only person who will ever use it,
then do whatever you like. Once you start writing code
that other people will use, or apply for a job and submit
code like this, you'll realize that what you 'want' is
totally the opposite of what most people want or expect.
 
U

Uri Guttman

L> I see your point, but I miss "real" passing by reference from Pascal
L> and Ada. But C, Perl and Java seem to want to bury it :(

you still don't get it. perl has real pass by ref in @_. copying @_ to
lexicals makes it pass by value. you have both in perl and you also have
explicit pass by ref when you use refs which is a third option. perl is
more flexible about passing args than most langs. and wait until you see
perl 6! :)

and note that classic pass by ref was nasty too with unintended side
effects being a tough bug to find. perl allows that but the standard
idiom of copying @_ to lexicals eliminates that bug.

again, trust me when i say have the callers pass in a real ref. it is
safer, more explicit (less bug prone) and will teach them better
perl. very very few exported functions on cpan do pass by ref as you
want it. and don't even think about it for object oriented code as that
is even nastier in breaking OO contraints.

uri
 
T

Tad McClellan

Jim Gibson said:
Larry said:
The following code snippet shows how I do "pass by reference" in
Perl. It works fine, but I'm wondering... is there a less verbose way
to do this?

Perl already implements a kind of pass by reference in the @_
argument.

#!/usr/bin/perl -l
sub squareMe {
$_[0] *= $_[0];


I don't like the $_[0] method, because it doesn't give me a chance to
name my variables.... I prefer names, not numbers, thank you! :)

$_ is a name, just not a pronounceable one!


I've heard it pronounced "dollar underwear".
 
D

Dr.Ruud

Larry schreef:
I don't like the $_[0] method, because it doesn't give me a chance to
name my variables.... I prefer names, not numbers, thank you! :)

See Data::Alias.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top