Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>While the accepted answer implements a <code>map</code>-like function, it does NOT do it in the way perl would. An important part of <code>for</code>, <code>foreach</code>, <code>map</code>, and <code>grep</code> is that the <code>$_</code> they provide to you is always an alias to the values in the argument list. This means that calling something like <code>s/a/b/</code> in any of those constructs will modify the elements they were called with. This allows you to write things like:</p> <pre><code>my ($x, $y) = qw(foo bar); $_ .= '!' for $x, $y; say "$x $y"; # foo! bar! map {s/$/!!!/} $x, $y; say "$x $y"; # foo!!!! bar!!!! </code></pre> <p>Since in your question, you have asked for <code>Map</code> to use array references rather than arrays, here is a version that works on array refs that is as close to the builtin <code>map</code> as you can get in pure Perl.</p> <pre><code>use 5.010; use warnings; use strict; sub Map (&amp;\@) { my ($code, $array) = splice @_; my @return; push @return, &amp;$code for @$array; @return } my @sample = qw(1 2 3 4 5); say join ', ' =&gt; Map { $_ * $_ } @sample; # 1, 4, 9, 16, 25 say join ', ' =&gt; map { $_ * $_ } @sample; # 1, 4, 9, 16, 25 </code></pre> <p>In <code>Map</code>, the <code>(&amp;\@)</code> prototype tells perl that the <code>Map</code> bareword will be parsed with different rules than a usual subroutine. The <code>&amp;</code> indicates that the first argument will either be a bare block <code>Map {...} NEXT</code> or it will be a literal code reference <code>Map \&amp;somesub, NEXT</code>. Note the comma between the arguments in the latter version. The <code>\@</code> prototype indicates that the next argument will start with <code>@</code> and will be passed in as an array reference.</p> <p>Finally, the <code>splice @_</code> line empties <code>@_</code> rather than just copying the values out. This is so that the <code>&amp;$code</code> line will see an empty <code>@_</code> rather than the args <code>Map</code> received. The reason for <code>&amp;$code</code> is that it is the fastest way to call a subroutine, and is as close to the multicall calling style that <code>map</code> uses as you can get without using C. This calling style is perfectly suited for this usage, since the argument to the block is in <code>$_</code>, which does not require any stack manipulation.</p> <p>In the code above, I cheat a little bit and let <code>for</code> do the work of localizing <code>$_</code>. This is good for performance, but to see how it works, here is that line rewritten:</p> <pre><code> for my $i (0 .. $#$array) { # for each index local *_ = \$$array[$i]; # install alias into $_ push @return, &amp;$code; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload