Build your array with push
PhilHibbs
created: 2006-01-31 09:21:27
Some ideas are so simple that they sometimes do not seem to be worth mentioning. This is one of them.

Don't write this:

my @folk = ("Hibbs",
            "Daglish",
            "Schwartz",
            "Vroom");
Write this:
my @folk = ();
push (@folk, "Hibbs");
push (@folk, "Daglish");
push (@folk, "Schwartz");
push (@folk, "Vroom");
Why? It's easier to maintain. You can insert or remove any single line easily, at the beginning, middle, or end. You can remove all the hard-coded lines, or move them to a later point (inside a loop, maybe).

The down-side is that the array name has to be repeated on each line, and there is probably a slight performance penalty.

Now you're going to show me something that uses "qw", aren't you? OK, go ahead, but don't forget to show me how it looks when an entry contains spaces.

Re: Build your array with push
created: 2006-01-31 09:26:25

I don't like the push way of constructing arrays. I use the following idioms:

my @array = (
  "Hibbs",
  "Daglish",
  "Schwartz",
  "Vroom",
);

... which works well for adding in any place, and also (un)commenting entries. If I'm sure there are no newlines/whitespace-only elements in the array needed, I also may use the following:

my @array = grep { /\S/ } split /\n/, '
foo
bar baz

and so on
';

depending on how my input data gets delivered (multi-column Excel data fits better into this model for example).

Re^2: Build your array with push
xdg
created: 2006-01-31 10:12:33
my @array = (
  "Hibbs",
  "Daglish",
  "Schwartz",
  "Vroom",
);

I agree. And the little thing that makes this really work well is training oneself to add that trailing comma (after "Vroom") to the last entry. (Ditto for hashes entries, too.)

-xdg

Code written by xdg and posted on PerlMonks is [http://creativecommons.org/licenses/publicdomain|public domain]. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re^2: Build your array with push
created: 2006-01-31 11:15:51
Something in me really doesn't like that trailing comma, which I wouldn't have expected to work. I suspect it's just an old habit, as it doesn't work in C & C++, which is still there lurking at the back of my mind and occasionally poisoning the Perl code that I write. OK, I'll try and get used to it, and thanks for introducing me to it - I trust that it really has no effect.

Now to get back some of that lost XP by upvoting the helpful replies...

ah, I like being a Friar anyway, it goes with my T-shirt.

Re^3: Build your array with push
created: 2006-01-31 11:44:01
you don't have to merely trust; it's documented in perldata:
You may have an optional comma before the closing parenthesis of a list literal
In fact, you can have extra commas anywhere you want in a list except (for reasons I can't explain) at the very front of it. They will not cause undef items to be created, nor will including nested empty lists.
my @items = ((),,,,5);
print "<$_>\n" for @items;
# prints only one item

Caution: Contents may have been coded under pressure.
Re^3: Build your array with push
created: 2006-01-31 14:40:11

Actually it does work in C, and that's most likely where perl picked up the habit too. One reason it's very useful is when you're generating code with macros, it's much easier to append commas to things than to insert them between things.

--
integral, resident of freenode's #perl
Re^4: Build your array with push
created: 2006-02-06 12:45:17

No, it does not.

$ cat > a.c
int a[] = (1,2,3,);
$ gcc -c a.c
a.c:1: error: syntax error before ')' token

Not even in C++

$ cat > a.cpp
int a[] = (1,2,3,);
$ gcc -c a.cpp
a.cpp:1: error: expected primary-expression before ')' token
Re^5: Build your array with push
created: 2006-02-07 05:14:17

It helps to remember that in C you need to use {} as brackets around a compound initialiser (something which is different from perl, where , has taken on a much greater role).

thaum:/tmp bsmith$ cat >a.c
int a[] = { 1, 2, 3, };
thaum:/tmp bsmith$ gcc -c a.c
thaum:/tmp bsmith$ 

--
integral, resident of freenode's #perl
Re^2: Build your array with push
created: 2006-01-31 15:23:11
I don't like the push way of constructing arrays.

You think that's bad, I once had to maintain a program that did this:

my @array;
$array[$#array] = "Hibbs";
$array[$#array] = "Daglish";
$array[$#array] = "Schwartz";
$array[$#array] = "Vroom";
...
And so on for about 30 lines.

One of the few times I felt justified in regexing some code.

Re^3: Build your array with push
created: 2006-01-31 15:26:03
Woah, woah, woah. That code just replaces the last element multiple times. Did you maybe mean
$array[@array] = "Hibbs";
or
$array[++$#array] = "Hibbs";
?

Caution: Contents may have been coded under pressure.
Re^4: Build your array with push
created: 2006-01-31 16:31:24
Nope, I meant what I said, believe it or not. The program never worked correctly, and that was one of many reasons why. (No strict, either.) Amazingly, this one dude had been working on it for six weeks before I saw it.
Re^2: Build your array with push
created: 2006-02-01 11:35:58

I use the former idiom as well, but I've run across this style a couple of times, too:

my @array = (
   'Hibbs'
  ,'Daglish'
  ,'Schwartz'
  ,'Vroom'
);

The one time I had the chance to actually ask a coder about that style, he gave me two rationales. First, he liked it because of a string-cat convention that's similar:

my $string =
   'this is a very long string that has a certain number '
  .$number
  .' of segments.'
  ."\n";

In print statements, this coder often mirrored that convention using commas instead of periods to pass the list of strings to [doc://print]. (This is apparently faster, though it smacks of premature optimization to me. But I digress.)

The second reason was that he found the trailing comma to be confusing; by moving commas to the front, he provided a visual reminder to put the comma in when adding to the list but without the "confusing" trailing comma. To each their own, I guess.

Anyone have thoughts on this style? Just curious as to what advantages/disadvantages there might be.

<-radiant.matrix->
A collection of thoughts and links from the minds of geeks
The Code that can be seen is not the true Code
I haven't found a problem yet that can't be solved by a well-placed [http://en.wikipedia.org/wiki/Trebuchet|trebuchet]
Re^3: Build your array with push
created: 2006-02-06 12:50:16

That doesn't really help here since you can't insert at the top safely.

The style has been called [http://perl.4pro.net/pcs.html|The Perlish Coding Style]. Accoding to that document, the following would be the proper alignment:

{ my @array = ( 'Hibbs'
              , 'Daglish'
              , 'Schwartz'
              , 'Vroom'    )

; my $string = 'this is a very long string that has a certain number '
             . $number
             . ' of segments.'
             . "\n"
}
Re: Build your array with push
created: 2006-01-31 09:30:20

Personally I don't see any evident maintainability that initialization-by-[doc://push]es buys me over the "standard" one that any decent text editor couldn't give me just as easily. The only "problem", if you really, really want to call it a problem, may have to do with the first and last entry. If you're really, really that concerned about the few extra keystrokes these may involve, then you how 'bout

my @folk = (
            "Hibbs",
            "Daglish",
            "Schwartz",
            "Vroom"
           );

instead?

Re: Build your array with push
created: 2006-01-31 09:35:42
my @folk = qw(Hibbs Daglish Schwartz Vroom),
           "Node Reaper";

my @folk = map {s/_/ /g; $_}
           qw(Hibbs Daglish Schwartz Vroom
              Node_Reaper);
---
$world=~s/war/peace/g

Re^2: Build your array with push
created: 2006-01-31 10:39:45
First one doesn't work, second one is grasping at straws.

Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re^3: Build your array with push
created: 2006-01-31 10:48:54

Neither work. Second one has the dreaded can't modify read only string error. Which is a good example of the issues the OP was making I guess. Sigh, i should know better for both of these too. :-(

I will quibble with the "grasping at straws" comment tho. I think this approach often is just fine for dealing with spaces in a qw() string.

---
$world=~s/war/peace/g

Re^4: Build your array with push
created: 2006-01-31 10:54:42
My problem with the second approach (apart from the "read only" snag) is that it turns constant data into something that requires computation. Certainly, there are times when computation is necessary with constant data, such as when you are constructing a data structure like an array of arrays: you take tab-separated data, split on the tabs, and produce array references. That's certainly easier and faster to write than producing the data structure in the code itself. But in this case, I think it was overkill.

Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re^5: Build your array with push
created: 2006-01-31 11:06:16

Right, I can see your point. I think for me it would come down to a matter of whether run time issues are more important than development time issues. Generally I'd say that development time is more important so I'd probably go with whatever saved me the most work.

---
$world=~s/war/peace/g

Re: Build your array with push
created: 2006-01-31 11:06:52
use YAML qw( Load );

my @folk = @{ Load( <


Re: Build your array with push
created: 2006-01-31 11:37:19
Yeah, but what if you've misspelled a name? Shouldn't it be easy to fix those kinds of mistakes? That's why I'd recommend formatting like...
my @folk = ();
push (@folk,
             "H".
             "i".
             "b".
             "b".
             "s"
                );
push (@folk,
             "D".
             "a".
             "g".
             "l".
             "i".
             "s".
             "h"
                );

...etc. Of course that's also problematic if you want to edit an individual letter. So I find the style below a bit better (especially when using a modern editor like edlin). Plus it uses a more descriptive name than the bland "@folk"...
push (@Hibbs_Daglish_Schwartz_Vroom,
                                    chr(0b1001000).
                                    chr(0b1101001).
                                    chr(0b1100010).
                                    chr(0b1100010).
                                    chr(0b1110011)
                                                  );
push (@Hibbs_Daglish_Schwartz_Vroom,
                                    chr(0b1000100).
                                    chr(0b1100001).
                                    chr(0b1100111).
                                    chr(0b1101100).
                                    chr(0b1101001).
                                    chr(0b1110011).
                                    chr(0b1101000)
                                                  );
push (@Hibbs_Daglish_Schwartz_Vroom,
                                    chr(0b1010011).
                                    chr(0b1100011).
                                    chr(0b1101000).
                                    chr(0b1110111).
                                    chr(0b1100001).
                                    chr(0b1110010).
                                    chr(0b1110100).
                                    chr(0b1111010)
                                                  );
push (@Hibbs_Daglish_Schwartz_Vroom,
                                    chr(0b1010110).
                                    chr(0b1110010).
                                    chr(0b1101111).
                                    chr(0b1101111).
                                    chr(0b1101101)
                                                  );
Re^2: Build your array with push
created: 2006-01-31 11:49:54
Of course, if you want to get rid of all that pesky horizontal scrolling you could pass something like the following through cpp...
p\
u\
s\
h\
(\
@\
H\
i\
b\
b\
s\
_\
D\
a\
g\
l\
i\
s\
h\
_\
S\
c\
h\
w\
a\
r\
t\
z\
_\
V\
r\
o\
o\
m\
,\
c\
h\
r\
(\
0\
b\
1\
0\
0\
1\
0\
0\
0\
)\
)\
;\

Re^3: Build your array with push
created: 2006-02-01 05:17:00

That won't work. Perl is not C.

Re^4: Build your array with push
created: 2006-02-01 15:15:08
That won't work. Perl is not C.
Perl is pretty close though. What part of Perl's syntax makes CPP choke (just curious)?
Re^5: Build your array with push
created: 2006-02-01 15:26:52
Oh, you said "pass it through cpp". Sorry, I didn't notice that. Then it would work.
Re^4: Build your array with push
created: 2006-02-01 15:35:05
Sure it will, but you need the -P command-line switch (which is not recommended), cpp and sed.
$ perl -P -MO=Deparse cpp.pl
:1:2: warning: backslash-newline at end of file
push @Hibbs_Daglish_Schwartz_Vroom, 'H';
cpp.pl syntax OK
Re^2: Build your array with push
created: 2006-02-01 05:25:05

That style of code is totally ugly and unusable. What if your original list of data erroneously switched two characters and you now have to swap the last and next-to-last character? This coding style is flawed in that aspect. You should use the following coding style instead:

push (@Hibbs_Daglish_Schwartz_Vroom, ""
         . chr(0b1010110)
         . chr(0b1110010)
         . chr(0b1101111)
         . chr(0b1101111)
         . chr(0b1101101)
     );

Actually I use this coding style when manipulating SQL SELECT statements:

SELECT monkey, bananas from my_table
  where 1 = 1
  and   flung_poo is null
  and   size > 800
;
Re^3: Build your array with push
created: 2006-02-06 03:11:06
That style of code is totally ugly and unusable [...] You should use the following coding style instead:

No, no, no! Yours is better than the previous alternatives but one may still get confused when swapping bits. And all those calls to [doc://chr], oh my! Now [doc://pack] can do all this for cheap. Thus you should use the following coding style instead:

push @Hibbs_Daglish_Schwartz_Vroom, pack qw/(B8)*
01010110
01110010
01101111
01101111
01101101
/;

Except that one would almost certainly want to write a specialized sub to do this, should he later change his mind with respect to the order in which to store bits into chars, chars into strings and strings into the array:

sub insert (\@@) {
    my $arr=shift;
    push @$arr, pack '(B8)*', @_;
}

# ...

insert @Hibbs_Daglish_Schwartz_Vroom,
qw/
  01010110
  01110010
  01101111
  01101111
  01101101
/;
Re: Build your array with push
created: 2006-01-31 11:59:35
my @folk = ( Hibbs => Daglish => Schwartz => Vroom => "and with spaces" );

perlmonks.org content © perlmonks.org and ambrus, Anonymous Monk, blazar, bmann, Corion, demerphq, Fletch, friedo, ikegami, integral, japhy, PhilHibbs, radiantmatrix, Roy Johnson, xdg

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03