0

there - just started learning Perl.

This is what I'm doing to get an array into a subfunction - can it be done simpler in 1 line?

sub my_sub {
    my $ref_array = shift;
    my @array = @$ref_array;
}
Chris R
  • 735
  • 1
  • 9
  • 17
  • 4
    Can *what* be done simpler? What are you trying to do? Why copy the array in the first place?? – tchrist Jan 28 '11 at 23:13
  • 1
    Why are you using pass by reference on a single array, and then going to the trouble to make a completely new copy of it? Why not just use `@_` *in situ*? – tchrist Jan 28 '11 at 23:28

4 Answers4

6

If you want the effect of the shift as well,

sub my_sub {
    my @array = @{+shift};
}

The unary + operator forces shift to be treated as an expression, not a variable name. (Otherwise @{shift} means the same as @shift.)

ephemient
  • 198,619
  • 38
  • 280
  • 391
  • 8
    This is pretty useless. I don’t believe the poster explained what he needs done well enough. Also, I despise tricksy `+shift` for people who can't be bothered to write the infinitely clearer `shift()`. – tchrist Jan 29 '11 at 00:01
  • 3
    TMTOWTDI; I like `+shift` better than `shift()`. Honestly, this is closer to OP's original than other answers are, and I don't think there's enough context to say that this *isn't* the right thing to do. – ephemient Jan 29 '11 at 00:12
  • 2
    IMHO "`+shift`" is a lot less readable and maintainable. And as tchrist noted in a separate comment, there's no seeming point to passing an array by reference only to turn it into a non-referenced array by copying. – DVK Jan 31 '11 at 21:39
  • Lately, I've been writing `@{shift @_}` in situations where I need to disambiguate from a bareword. Does the job and uses the extra characters to actually explain what is going on. – Eric Strom Jan 31 '11 at 22:11
3

Another approach is to not worry about it being an arrayref -- just leave it that way and use it in the rest of your sub as-is.

awwaiid
  • 176
  • 1
  • 3
2

You could simplify just as

sub my_sub { 
  my @array = @{$_[0]};
}

Where @_ is the default array/list, used in parameter passing.

Marc Bollinger
  • 3,109
  • 2
  • 27
  • 32
0

This is a heck of a lot cheaper:

local *array = shift();
tchrist
  • 78,834
  • 30
  • 123
  • 180
  • 3
    And not the least bit equivalent. – hobbs Jan 28 '11 at 23:52
  • 1
    In trying to learn the mid-level Perl magic, can I ask, what is it that you are setting to what here? Are you setting a reference to @array to the arrayref that has been passed in? How do you know that you create @array and not %array or $array? Where can I learn more about this * operator (perlop?). Thanks! – Joel Berger Jan 29 '11 at 00:37
  • 5
    @tchrist: Why the hostility? It *would* make your posts better if you provided a little more explanation. If you think his example is "nonsense", it would be useful to explain *why* in your own answer and then explain why your alternative is better. There is an art to giving good answers, and getting upset in the comments is not a sign you're on that path. – Cody Gray - on strike Jan 29 '11 at 05:37
  • 1
    @Cody - leaving aside communications issues (I am eminently less qualified to argue writing styles that tchrist, independently of which of you I agree with), he is correct on substance. The OP basically asked an ambiguous question that doesn't HAVE an answer as asked: – DVK Feb 01 '11 at 01:41
  • @Cody,@hobbs - 1. if he asked "how do I pass array to a method by reference" and access it, the answer is "use `$arr->[$i]` without bothering to stuff arrayref into array"; 2. If he asked "how do I pass an array by VALUE", the answer is "just pass the bleeding array in without a reference in the first place"; 3. If he asked "how to pass an array by reference and then make a copy of it", the answer is "unless there's a good reason to do it just this way, it's a bad idea to do so - either pass by value OR by reference; and if you DO have a reason, the code you have is the most readable possible" – DVK Feb 01 '11 at 01:46
  • @DVK: To be honest, I neither know nor care much about substance. I've never written a Perl script in my life. I was just observing the comments that had been made (and now deleted), as they were being flagged as spam by a number of users. I assumed this was not necessarily tchrist's true intention, so it would be polite to let him know that was the case and make a few suggestions on improvements. Now back to your regularly scheduled discussions. ;-) – Cody Gray - on strike Feb 01 '11 at 10:19
  • @Joel - (1) I would strongly suggest you ask your question as a separate SO Perl question (you can link to this answer in it) - it's worth its own extended explanation. (2) "`*`" is called a "glob" (which gives you hellovatime googling for it since there's of course the similarly named `glob()` function for listing files :) . Among good references are http://perldoc.perl.org/perlref.html , "Symbol Tables" entry in http://perldoc.perl.org/perlmod.html#Symbol-Tables and http://perldoc.perl.org/perlsub.html#Passing-Symbol-Table-Entries-%28typeglobs%29 – DVK Feb 01 '11 at 16:11