sulfericacid has asked for the wisdom of the Perl Monks concerning the following question:

I have a few more questions from reading Learning Perl 3.. In the following example I understand that it's saying "anything that says fred and/or barney in the line should be put in uppercase letters like FRED or BARNEY". What I don't understand is what $1 is doing in all of this or what /gi is doing. I *think* g means to search and replace the whole word so it won't match manfred, or somethine along those lines.
$_ = "I saw Barney with Fred"; s/(fred|barney)/\U$1/gi;
In the next example I have a question on efficiency. I know sometimes joining is the only option to add things betweens characters. But if the solution is as simple as this couldn't you just write my $x = "4:6:8:10:12"; ? That would remove the useless need of join and a lot of messy commas.
my $x = join ":", 4, 6, 8, 10, 12;
Thanks for your help everyone.

"Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

sulfericacid

Replies are listed 'Best First'.
Re: Learning Perl 3 questions (misc)
by zengargoyle (Deacon) on Mar 22, 2003 at 03:31 UTC

    • the 'g' means global. without it only the first 'fred' or 'barney' would be changed.
    • the 'i' means ignorecase. without it the regexp would not match 'Fred' or 'BaRnEy', with it it does.
    • the '$1' means whatever was matched by the first set of '()', in this case it could be 'badmatchfred' or 'fredom' or 'Barneycorn' or ...
    • join is handy because if you wanted to change the seperator on the fly:
      join $sep, $one, $two, $three;
      is less typing than
      "$one$sep$two$sep$three"; # well in the long run anyway =P
    • please don't go worrying yourself about efficiency for at least a couple of months or your head will start to explode when you start map'ing and sort'ing and writing code like
      sub this { "This" } sub that { "That" }
      for perfectly good reasons.

Re: Learning Perl 3 questions (misc)
by data64 (Chaplain) on Mar 22, 2003 at 02:59 UTC

    $1 is what was matched in the first set of parenthesis. If there were more sets of parenthesis', then it would be available in $2, $3. Of course there are some execptions to this but no point trying to confuse you more at this point.

    Most definitely, the join in that example is not really needed and is probably there just to demonstrate how join could be used. In real life, not calling join is going to be faster than calling join.


    Just a tongue-tied, twisted, earth-bound misfit. -- Pink Floyd

Re: Learning Perl 3 questions (misc)
by MrYoya (Monk) on Mar 22, 2003 at 03:47 UTC
    In the first example, the $1 is what was in the first set of parenthesis. You'll be seeing that one a lot if you use regular expressions.. regularly. :)

    As for the /gi, adding /g to the end of a regular expression makes it so that it won't give up after the first match, and will do it to all the matches that it could. Check out these two lines:

    perl -e 'my $x = "fredfred"; $x =~ s/(fred)/\U$1/; print $x' FREDfred

    perl -e 'my $x = "fredfred"; $x =~ s/(fred)/\U$1/g; print $x' FREDFRED

    In the first example, the $x variable was set to "fredfred", then the first match it could find was uppercased. In the second, all the matches it could find were uppercased.

    The /i at the end means "ignore case", which means if $x = "fRedFREd" or $x = "FRedFrED" the regex would still match.

    You are right about the join code. However, it all comes down to what you find most convenient. If you had to add 14 and 15 to that list of numbers, which one would be easier to work with?

    Hope this helps.

Re: Learning Perl 3 questions (misc)
by The Mad Hatter (Priest) on Mar 22, 2003 at 03:36 UTC
    The g means to search the whole string and the i searches case-insensitively (so that FrEd still matches). The \U just uppercases everything (in this case $1). As for the $1 and join, data64 pretty much has it covered.

    Update: zengargoyle has also done a good (and probably better) job of explaining it piece by piece.

Re: Learning Perl 3 questions (misc)
by benn (Vicar) on Mar 22, 2003 at 15:19 UTC
    To round off, just a quick comment on 'join' that may clarify things. As zengargoyle says, you don't need to worry about the efficiency of built-ins - if a language has a command, it's usually worth using it, rather than 'rolling your own'.

    In the example you give though, if "$x='4:6:8'" is exactly what you want to end up with, then by all means, type it out in full. In most real-life situations though, that list of numbers is likely to come from somewhere else - my $x = join(":",@list_of_user_supplied_data" or something.

    Also, from a readability point of view, seeing a 'join(":")' followed later by a 'split(":")' makes your intention more obvious.

    Hope this helps.
Re: Learning Perl 3 questions (misc)
by sulfericacid (Deacon) on Mar 23, 2003 at 13:05 UTC
    Ok, thanks everyone of helping me with this. From all the explanations each of you gave it made all this really clear to me now.

    Thanks again fellow monks :)

    "Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

    sulfericacid