Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebApp::Template condition behaviour and use of variables

Tags:

raku

cro

Using the template language provided I always have access to $_ or or Hash referent for iteration which is fine.

# In routes
get -> 'somestuff' {
  my $stuff = %{ arr => [ {stuff => 'stuff1' , nbr => 1 }, {stuff => 'stuff2', nbr => 2 } ] };
  template 'somestuff.crotpl', $stuff;
}
# In somestuff.crotpl
<?$_.elems>
<$_> <br>
<@arr> <.stuff> = <.nbr> <br> </@>  
</?>

But testing for non-existant key/value <?{.not-here}> ...</?> throws an exception, is it a normal behaviour ?

I seems that variables, as not stated in the docs, are only usable when calling them from a template subroutine with no correlation to the route context (As shown in the test-file : https://github.com/croservices/cro-webapp/blob/master/t/test-data/cond-var.crotmp). Also testing for a non-existant variable also throws an exception.

like image 689
kolikov Avatar asked Nov 19 '19 17:11

kolikov


1 Answers

The documentation for a <.foo> dereference is as follows:

If the current topic does the Associative role, then this form will prefer to take the value under the name hash key, falling back to looking for a method name if there is no such key.

Thus, if there is no such key then it will indeed fall back to a method call, and (as is usually the case in Raku) it's an error if there is no such method. So yes, it's expected behavior.

There are also unambiguous forms that will always do a hash access (soft failure) or method dispatch (error if no such method. Again, quoting the relevant bit of the documentation:

  • <.elems()> will always be a method call, even if used on an Associative (so can be used to overcome the key fallback)
  • <.<elems>> will always be a hash index

These apply consistently across the template language, so <$var<foo>> or <?{ $var<foo> }> may be used (granted the documentation could probably spell that out a bit more clearly).

The only variable in scope at the top level of a template is $_, which is initialized to the value passed when calling template. Iteration, subroutines, and macros may all introduce variables. As noted in the docs:

It is a template compilation time error to refer to a variable that does not exist.

Meaning that they follow the same rules as lexical variables in Raku. The error is produced at template compilation time, meaning one can write a unit test that compiles all templates to ensure the absence of at least that kind of mistake.

In general, the template languages follow Raku semantics, the only significant discrepancy being that <.foo> acts on Associative things more like .<foo>:exists ?? .<foo> !! .foo.

like image 60
Jonathan Worthington Avatar answered Nov 19 '22 15:11

Jonathan Worthington