[Petal] Re: Using Test::More

Fergal Daly fergal at esatclear.ie
Wed Apr 9 17:09:16 BST 2003


On Wednesday 09 April 2003 09:38, you wrote:
> > My new codegenerator passes all except 17 tests. Most of those are things 
I 
> > just didn't implement yet.
> 
> What is the difference between your CodeGenerator and the one I wrote? 
> I'm curious :)

One big difference is that it turns the PIs into a tree of objects and then 
optimises the tree if possible (there's not much optimising needed for the 
PIs generated by Petal but when I was generating stuff directly from XML 
there was lots to do)

<?if name="a"?>hello<?else?<goodbye<?end?>

To construct a tree for this by hand, you would do something like

cond(
	hash("a"), # the condition
	str("hello"), # the object to render for true
	str("goodbye") # the object to render for false
)

The object created by cond knows that it has three parts and it does something 
like this

$cond_perl = $self->{Condition}->perl; # $hash->{"a"}
$true_perl = $self->{True}->perl; # $ouput .= "hello"
$false_perl = $self->{False}->perl; # $output .= "goodbye"

return <<EOM;
if ($cond_perl)
{
	$true_perl;
}
else
{
	$false_perl;
}
EOM

I don't think this gives any speed advantage compared to the current way of 
doing things.

One thing that does give a speed advantage is using a string instead of an 
array to store the built template. My code can switch between using a string 
or an array and the difference is up to 30% improvement with strings, so it 
might be worth doing that inside Petal's CodeGenerator.

The main difference is that I don't use the Petal hash, I just use an ordinary 
hash. I parse all the expressions beforehand so compile time is longer but 
then execution is speeded up a lot.

So where Petal generates

if ($hash->get("a/method $c 'd'")
{
	...
}

I generate something like

if( $hash->{a}->method($hash->{c}, "d") )
{
	...
}

My benchmark is processing a template from a Chinese dictionary program. 
Before you improved the Hash code there was a massive speedup around 30-40 
times but now it's only about 3 times faster.

I'll try just integrating the expression parsing (and forgetting about all my 
other stuff). It should be possible to speed things up considerably.

> I think it should always fetch the local variable first. 'local' is 
> misleading for us Perl freaks, I think we should be really read it as 'my'.

Sounds right to me, I'd like to find out what Zope does but I don't have it 
installed.

> I think ;; is a mistake. There is a well known mechanism to escape meta 
> characters which is used by almost everything out there which consists 
> of backlashing them, which is why I consciously broke this TALES rule.
> 
> Why re-invent the wheel?

I defintely agree with you, ;; makes the parsing much trickier.

> Come to think of it, there are quite a few differences between TALES and 
> PETALES (which is entirely defined in the Petal::Hash::Var module). With 
>   Petal expression syntax, you can.
> 
> * Pass parameters to methods that you call, which I find extremely handy
> * NOT use the pipe (|) symbol (but this should really be implemented)
> * Use \ to escape any character
> * Use the '.' symbol in place of '/'.
> 
> The more I think about all this and the more I think that PETALES should 
> really be the same as TALES. BUT:
> 
> * I don't like the ';;' rule.
> * I would like to remove the '.' as an alias of the '/', but it would 
> break backwards compatibility, so we need to have a one-liner option to 
> keep the old module somewhere so that it's still possible to run 
> templates with the old behavior.
> * I still need to be able to pass parameters to methods from the template.

I think passing params is defintely useful.

My parser does pipes but it doesn't do evals or extensions yet and it does a 
bad job of globals.

One other thing my parser does is allow

a/hash_key/5/get()

to be written as

a{hash_key}[5]->get()

If you know that $hash->{a} is a hashref and $hash->{a}->{hash_key} is an 
array ref and $hash->{a}->{hash_key}->[5] is an object then it doesn't have 
to think about types at runtime. When I rewrite my benchmark template to take 
advantage of this, it almost doubles in speed again but it's a big break in 
compatibilty with TALES.

I'll try get something uploaded that you can look at but I'm currently jobless 
and I have an interview tomorrow (and hopefully another soon after) and then 
I'm going away for a week so you may have to wait to see my stuff,

F



More information about the Petal mailing list