On Aug 17, David T-G said:

>% That's good of you to show how you'd do it in another language (yes, even
>% if that language is PHP ;) ), because it clears up what you want to do.
>
>Indeed.  It was the most succinct way to explain it :-)

This list (and many others) often receives questions about code without
ever showing even pseudo-code.  PHP has similar-enough syntax to Perl, so
it's fine.

>The
>
>  s{#(.*?)#}
>
>appears to look for my template strings.  And so then the {}ge part looks
>similar to a standard s///ge, so that's probably where it's doing the
>real work.

Yes.  I'm using s{}{} instead of s///.  I prefer the use of {} delimiters
when I'm doing a s///e, because it better represents the "code" aspect of
the replacement.

>I can somewhat follow the work (thanks for your patience, if you're
>reading along with me).  Based on a match like #NAME_FIRST# found in the
>first line, we're going to look up the value pointed to by that hash key
>in the xlate hash I built.  I have to figure that
>
>  { $xlate{$1} }
>
>means to return that to the caller, even though it isn't return()ed or
>print()ed or whatever.

Yes; perhaps I should have been more explicit and said 'return ...'.

>So then we get to the really confusing part...   AIUI we matched
>
>  #key#
>
>but here we either say that we should spit
>
>  #key
>
>back out or the #$1 means something that I don't get.

Sorry, that was my typo.  It should be

  else { return "#$1#" }

That is, if the text found between #'s isn't a key in the hash, just
return the text with the #'s on either side of it.

>%   my $keys = join '|', map quotemeta, keys %xlate;
>%   # quotemeta() make's sure any regex-characters in the keys are escaped
>%
>%   $string =~ s/#($keys)#/$xlate{$1}/g;
>
>It's that funky map thing, though.  I don't have much experience with
>that :-)

A simple way to look at map() and grep() is that they are merely for-loops
that automatically build up a return list for you.  Here's a brief look at
their equivalence:

  @data = map { TRANSFORMATION } LIST;
  # is
  @data = ();
  for (LIST) {
    push @data, TRANSFORMATION;
  }

  # and

  @data = grep { CONDITION } LIST;
  # is
  @data = ();
  for (LIST) {
    push @data, $_ if CONDITION;
  }

Compounded to this is the fact that both functions can be called with an
EXPRESSION, rather than a BLOCK:

  @halves = map $_/2, @numbers;
  @halves = map { $_/2 } @numbers;

mean the same thing really.  I used the 'expression' syntax.

>Oh, I think I get it...  We're only pulling the keys out of %xlate, and
>we're quoting them to be safe.  And you picked '|' for the join because
>that's a regexp or, right?  So my expr ends up being like
>
>  s/#(NAME_FIRST|NAME_LAST...)#/...
>
>and the replacement is the bucket value of the key in the hash.  Hey,
>that's slick.

Exactly.

>So why the map?  Is that just a way to apply quotemeta to each key in the
>hash?

Yes.  If we wrote the map() as a for loop:

  my @safe;
  for (keys %xlate) {
    push @safe, quotemeta;  # it's default arg is $_
  }
  my $pattern = join '|', @safe;

-- 
Jeff "japhy" Pinyan      [EMAIL PROTECTED]      http://www.pobox.com/~japhy/
RPI Acacia brother #734   http://www.perlmonks.org/   http://www.cpan.org/
<stu> what does y/// stand for?  <tenderpuss> why, yansliterate of course.
[  I'm looking for programming work.  If you like my work, let me know.  ]


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to