CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate: Re: [cf8geek] Bareword found/operator expected/missing semicolon?: Edit Log



Laurent_R
Veteran / Moderator

May 29, 2016, 2:28 AM


Views: 10890
Re: [cf8geek] Bareword found/operator expected/missing semicolon?

Hi,

let me just provide an example where prototype definition might be useful.

Suppose you want to write in pure Perl your own custom version of the map (or grep or sort) builtin function.

You could do something like this:


Code
sub my_map { 
my $code_ref = shift;
my @d ;
push @d, $code_ref->($_) for @_;
return @d;
}


You would need to call it with something like this:


Code
print join " ", my_map (sub{$_ * 2}, 1..5);


The calling syntax is a bit ugly. If I put my_map in a module and make it available, it is doubtful that many people will want to use it with such a syntax.

With prototype, I can write:

Code
sub my_map (&@){ 
my $code_ref = shift;
my @d;
push @d, $code_ref->($_) for @_;
return @d;
}


Now, the calling syntax can be the same as the original map calling syntax:

Code
my @array = 1..5; 
print join " ", my_map {$_ * 2} @array;


Now, the calling syntax is a lot clearer, especially if you already know map and its calling syntax.

Of course, writing a my_map function that does the same thing as the original map function is not very useful (and less efficient for large input data), but you could think of versions of my_map that behave slightly differently and might be useful. For example, a version that does not modify the original array if you modify $_ within the code reference passed to my_map:


Code
sub my_map (&@){ 
my $code_ref = shift;
my @d = @_;
$_ = $code_ref->($_) for @d;
return @d;
}


Similarly, you could write a function looking like grep that exits as soon as it has found one element for which the code reference returns true (a sort of first function), except that it already exists in CPAN modules.

Note that for the examples above to work, the definition of my_map must come before its use, or, at least, you would need a prototype definition to occur before its use. For example the my_map version that does not modify the original array even if the code reference modifies $_:


Code
sub my_map(&@);  # the prototype must occur before the call 

my @array = 1..5;
print "New array: ", join " ", my_map {++$_} @array;
print "\nOriginal array: ", "@array", "\n";

sub my_map (&@){
my $code_ref = shift;
my @d = @_;
$_ = $code_ref->($_) for @d;
return @d;
}
# output:
# New array: 2 3 4 5 6
# Original array: 1 2 3 4 5


I hope this helps.


(This post was edited by Laurent_R on May 29, 2016, 3:13 AM)


Edit Log:
Post edited by Laurent_R (Veteran) on May 29, 2016, 2:30 AM
Post edited by Laurent_R (Veteran) on May 29, 2016, 2:32 AM
Post edited by Laurent_R (Veteran) on May 29, 2016, 3:13 AM


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives