[Israel.pm] Fwd: [Telux] Next Meeting: "High-Level Programming Concepts Using Perl 6" on 22-March

Shlomi Fish shlomif at iglu.org.il
Sat Mar 14 08:32:39 PDT 2009


Hi Evgeny!

On Saturday 14 March 2009 16:01:02 Evgeny wrote:
> Thank you, now it looks much better.
>

You're welcome.

> > I would write it like that: (untested)
> >
> > <<<<<<<<<
> > while (my ($key, $cb) = each(%matchers))
> > {
> >        if (my @subgroups = ($line =~ $key))
> >        {
> >                $cb->(@subgroups);
> >        }
> > }
>
> Will try not to post the whole messages this time. Just 1-2K :)
>

Thanks! I see it's much better now. There's still an HTML part, but I can live 
with that because KMail (and I assume most other MUA's) display the text part 
just fine.

>
> Now there is also another issue I remember having.
> How can I pass an unspecified amount of arguments to a function, since a
> function does not really care how many parameters it gets - I just read
> them one by one with "shift". I want to have a generic
> $callback->(.........) where instead of the dots I dont use an array, but
> "explode" this array into multiple arguments.
>
> In ruby it is done exactly like that   callback( * array )   where the * is
> exploding it.
>

Well, in Perl 5, every subroutine accepts an array (and returns one). It's up 
to you to decide how to extract the arguments from it. If you do 
<< $callback->(@array) >>, then @array will be clobbered into the @_ of 
$callback. So you can do for example (tested):

<<<<<<<<
#!/usr/bin/perl

use strict;
use warnings;

sub sing
{
    my ($first_name, $last_name, $song) = @_;

    print "$first_name $last_name sings $song\n";

    return;
}

{
    my @input1 = ("David", "Ben-Yishay", "Mizmor-Le-David");

    sing(@input1);
}

{
    my @input2 = ("Aretha", "Franklin", "Respect");

    sing(@input2);
}

{
    my @input2 = ("Jonh", "Lennon", qq{"Imagine"});

    sing(@input2);
}
>>>>>>>>

Passing an array to a function may not be as straightforward in case the 
function defines a prototype (which it usually shouldn't - see: 
http://www.perlfoundation.org/perl5/index.cgi?prototype ).

If you're interested in passing an array to a function without clobbering the 
rest of the argument list, then you should pass it as a reference using 
\@myarray, or [@myarray] (depending on what you want to do - see 
http://perldoc.perl.org/perlreftut.html ). Then you can just do inside the 
function:

<<<<<<<<
sub my_func
{
	my $my_array_ref = shift;

	# Do stuff with $my_array_ref like:
	print $my_array_ref->[$idx], "\n";

	print join (",",@{$my_array_ref}), "\n";
}
>>>>>>>>

Also note that, with methods, the first argument must be the object reference, 
and the rest of the arguments should follow it. That's because it is used to 
determine the package that the object is associated with and which method to 
call.

> Because, as you have seen, I would love to write the callbacks like this:
>
> Given('a (.*)', sub {
>    my $object = shift;
> })
>
> But since I can only pass an array, I end up with this:
> Given('a (.*)', sub {
>   my @params = shift;

This is wrong. You need either:

<<<
	my @params = @_;
>>>

Or:

<<<
	my $params = shift;
>>>

>   my $project = $params[0];
> })
>

You can pass the object as the first argument to the callback and then the 
rest of the params either flattened or as a reference:

* $callback->($object, @params);

* $callback->($object, \@params);

>
>
>
> Regarding you comments on DSL, it looks like you assume that I would want
> to parse the DSL ... well, in a way I guess I am parsing it. But not
> really. I rather thing that the actual DSL would be the language to write
> specification code - not the story specification itself.
>

Not sure I understand you.

> So where I use
>
>    sm(qr/Given a (.*)/, sub {
>      some code here;
>    })
>
> I would want a DSL to allow programmers to write it easier, with less
> syntax. Like in ruby's cucumber:
>
>   Given /a (.*)/ {
>     some code here;
>   }
>

Hmmmm.... not sure if the Perl 5 syntax is that flexible.

> And if there is anything that I can do to remove the extra syntax sugar
> from the perlish way, I would gladly do it. 

Just a note: the term "syntactic sugar" is used when the extra syntax is a 
good thing. The term you are looking for in this case is "syntactic salt".

> Since the engine (the final
> loop) is not being actively edited. But these matchers will be multiple and
> need to be written quite a lot, the simpler they are the better. (and
> naturally i dont want to parse it as a DSL ... but maybe if its easy then
> it is also a solution).

Well, writing a parser using Parse::RecDescent or a different parser generator 
is not too hard, but can be time consuming. I think every programmer worth his 
weight in salt (or sugar... ;-)) should know how to write parsers using yacc 
and similar tools. But note that embedding arbitrary Perl code inside may 
become nasty unless you have a good mechanism to delimit it (like here-
documents).

>
>
> Also thank you for the greedy/non-greedy examples and generally
> manipulating regexps. I will probably need it sometime later.
>

You're welcome.

Regards,

	Shlomi Fish

>
>
> Regards,
> Evgeny
>

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
Stop Using MSIE - http://www.shlomifish.org/no-ie/

God gave us two eyes and ten fingers so we will type five times as much as we
read.




More information about the Perl mailing list