I'm using perl and Template::Toolkit to generate some texts. In the perl program, I defined a hash ref such as
my $user = { "user-name" => "John" };
and passed it to Template::Toolkit in order to generate John with the template file. In the template file I wrote
[% user-name %]
But unfortunately, user-name seemed to be recognized as a subtraction expression (user minus name) by Template::Toolkit.
To confirm my suspicions, I looked into the manual of Template::Toolkit to find the valid tokens to use in the variable name but found nothing.
So my questions are:
Could you give the list of valid tokens for variable names of
Template::Toolkit?
Could I use some "escaping method" in the template file so that the
variable name in perl program could remain user-name?
Generally, a valid perl variable is a valid template toolkit variable.
The variable should always start with a non numeric, non symbolic character [ A to Z and _ ]
Variable can only contain a to z, 0 to 9 and _ (underscore) characters.
Variable names cannot contain special symbols (it includes '-' symbol ).
Eg:
$user-name is not a valid perl variable. but
$user_name is valid.
Here is what perl interpreter throws for your code
$ my $user = { user-name => "John" };
Compile error: Bareword "user" not allowed while "strict subs" in use at (eval 294) line 5.
If you really want to use 'user-name' then you should define like this
$ my $user = { "user-name" => "John" };
$ my $data = { user => $user };
And you should access it in your tt2 file like this:
[% user.item('user-name') %]
Related
I need to set a variable name from a string.
Here is my code :
var="cle"
value="1"
printf -v $var "$value"
echo $cle
I want it to output "1"
I am getting:
illegal option "-v"
I tried to replace printf by the declare function but, dash doesn't include it either.
The only way to do this in dash is to use eval, but that is risky unless you know that your string is a valid identifier.
expr "$var" : '[_[:alpha:]][_[:alnum:]]\{0,\}$' && eval "$var=$value"
The call to expr fails (or at least, is intended to fail) if the value of var is anything other than a single valid identifier.
I recently discovered what seems to be an undocumented variable in Perl, %_. I don't remember exactly how I stumbled across it (it was last week), but I had a typo in my code where I was using map and instead of $_->{key} I used $_{key}. When I found the mistake, I was surprised that it didn't generate an error, and I verified that use strict and use warnings were in place.
So, I did up a small test, and sure enough it runs without any warnings or errors:
$ perl
use strict;
use warnings;
print keys %_;
$
So, all I can figure is that %_ is defined somewhere. I can't find it in perlvar, so what's the deal? It doesn't have any contents in the script above.
Punctuation variables are exempt from strict. That's why you don't have to use something like our $_; before using $_. From perlvar,
Perl identifiers that begin with digits, control characters, or punctuation characters [...] are also exempt from strict 'vars' errors.
%_ isn't undocumented. From perlvar,
Perl variable names may also be a sequence of digits or a single punctuation or control character (with the literal control character form deprecated). These names are all reserved for special uses by Perl
You can have a hash named _ because _ is a valid name for a variable. (I'm sure you are familiar with $_ and #_.)
No Perl builtin currently sets it or reads %_ implicitly, but punctuation variables such as %_ are reserved.
Note that punctuation variables are also special in that they are "super globals". This means that unqualified %_ refers to %_ in the root package, not %_ in the current package.
$ perl -E'
%::x = ( "%::x" => 1 );
%::_ = ( "%::_" => 1 );
%Foo::x = ( "%Foo::x" => 1 );
%Foo::_ = ( "%Foo::_" => 1 );
package Foo;
say "%x = ", keys(%x);
say "%_ = ", keys(%_);
say "%::x = ", keys(%::x);
say "%::_ = ", keys(%::_);
say "%Foo::x = ", keys(%Foo::x);
say "%Foo::_ = ", keys(%Foo::_);
'
%x = %Foo::x
%_ = %::_ <-- surprise!
%::x = %::x
%::_ = %::_
%Foo::x = %Foo::x
%Foo::_ = %Foo::_
This means that forgetting to use local %_ (as you did) can have very far-reaching effects.
It's not undocumented, it's just unused. You'll find it's always empty
perldoc perlvar says this
Perl variable names may also be a sequence of digits or a single punctuation or control character ... These names are all reserved for special uses by Perl; for example, the all-digits names are used to hold data captured by backreferences after a regular expression match.
So %_ is reserved but unused.
Hash variables are the least common, so you will find that you can use %1, %( etc. as well (code like $({xx} = 99 is fine) but you will get no warning because of backward-compatability issues
Valid general-purpose variable names must start with a letter (with the utf8 pragma in place that may be any character with the Unicode letter property) or an ASCII underscore, when it must be followed by at least one other character
$_ is a global variable. Global variables live in symbol tables, and the built-in punctuation variables all live in the symbol table for package main.
You can see the contents of the symbol table for main like this:
$ perl -MData::Dumper -e'print Dumper \%main::' # or \%:: for short
$VAR1 = {
'/' => *{'::/'},
',' => *{'::,'},
'"' => *{'::"'},
'_' => *::_,
# and so on
};
All of the above entries are typeglobs, indicated by the * sigil. A typeglob is like a container with slots for all of the different Perl types (e.g. SCALAR, ARRAY, HASH, CODE).
A typeglob allows you to use different variables with the same identifier (the name after the sigil):
${ *main::foo{SCALAR} } # long way of writing $main::foo
#{ *main::foo{ARRAY} } # long way of writing #main::foo
%{ *main::foo{HASH} } # long way of writing %main::foo
The values of $_, #_, and %_ are all stored in the main symbol table entry with key _. When you access %_, you're actually accessing the HASH slot in the *main::_ typeglob (*::_ for short).
strict 'vars' will normally complain if you try to access a global variable without the fully-qualified name, but punctuation variables are exempt:
use strict;
*main::foo = \'bar'; # assign 'bar' to SCALAR slot
print $main::foo; # prints 'bar'
print $foo; # error: Variable "$foo" is not imported
# Global symbol "$foo" requires explicit package name
print %_; # no error
I have a string "/Name Pa$Name#my"
$myname = GetContent("Name")
GetContent is only gets the key and gives the value for that Key. I cannot modify the GetContent function.
If i execute above, as "Pa$Name#my" contains the '$' char, $myname gives me value as "Pa#my" and ignores "$Name" content.
What can i do to get the $myname = Pa$Name#my ? Can i append some special characters while assigning the $myname variable.
As far as I understand your trouble comes from the fact that the var $name does not exist. You can use single qotes if you don't want Powershell to look for vars :
$a = 'Pa$Name#my'
I have perl function I dont what does it do?
my what does min in perl?
#ARVG what does mean?
sub getArgs
{
my $argCnt=0;
my %argH;
for my $arg (#ARGV)
{
if ($arg =~ /^-/) # insert this entry and the next in the hash table
{
$argH{$ARGV[$argCnt]} = $ARGV[$argCnt+1];
}
$argCnt++;
}
return %argH;}
Code like that makes David sad...
Here's a reformatted version of the code doing the indentations correctly. That makes it so much easier to read. I can easily tell where my if and loops start and end:
sub getArgs {
my $argCnt = 0;
my %argH;
for my $arg ( #ARGV ) {
if ( $arg =~ /^-/ ) { # insert this entry and the next in the hash table
$argH{ $ARGV[$argCnt] } = $ARGV[$argCnt+1];
}
$argCnt++;
}
return %argH;
}
The #ARGV is what is passed to the program. It is an array of all the arguments passed. For example, I have a program foo.pl, and I call it like this:
foo.pl one two three four five
In this case, $ARGV is set to the list of values ("one", "two", "three", "four", "five"). The name comes from a similar variable found in the C programming language.
The author is attempting to parse these arguments. For example:
foo.pl -this that -the other
would result in:
$arg{"-this"} = "that";
$arg{"-the"} = "other";
I don't see min. Do you mean my?
This is a wee bit of a complex discussion which would normally involve package variables vs. lexically scoped variables, and how Perl stores variables. To make things easier, I'm going to give you a sort-of incorrect, but technically wrong answer: If you use the (strict) pragma, and you should, you have to declare your variables with my before they can be used. For example, here's a simple two line program that's wrong. Can you see the error?
$name = "Bob";
print "Hello $Name, how are you?\n";
Note that when I set $name to "Bob", $name is with a lowercase n. But, I used $Name (upper case N) in my print statement. As it stands, now. Perl will print out "Hello, how are you?" without a care that I've used the wrong variable name. If it's hard to spot an error like this in a two line program, imagine what it would be like in a 1000 line program.
By using strict and forcing me to declare variables with my, Perl can catch that error:
use strict;
use warnings; # Another Pragma that should always be used
my $name = "Bob";
print "Hello $Name, how are you doing\n";
Now, when I run the program, I get the following error:
Global symbol "$Name" requires explicit package name at (line # of print statement)
This means that $Name isn't defined, and Perl points to where that error is.
When you define variables like this, they are in scope with in the block where it's defined. A block could be the code contained in a set of curly braces or a while, if, or for statement. If you define a variable with my outside of these, it's defined to the end of the file.
Thus, by using my, the variables are only defined inside this subroutine. And, the $arg variable is only defined in the for loop.
One more thing:
The person who wrote this should have used the Getopt::Long module. There's a major bug in their code:
For example:
foo.pl -this that -one -two
In this case, my hash looks like this:
$args{'-this'} = "that";
$args{'-one'} = "-two";
$args{'-two'} = undef;
If I did this:
if ( defined $args{'-two'} ) {
...
}
I would not execute the if statement.
Also:
foo.pl -this=that -one -two
would also fail.
#ARGV is a special variable (refer to perldoc perlvar):
#ARGV
The array #ARGV contains the command-line arguments intended for the
script. $#ARGV is generally the number of arguments minus one, because
$ARGV[0] is the first argument, not the program's command name itself.
See $0 for the command name.
Perl documentation is also available from your command line:
perldoc -v #ARGV
Guys I'm new to Perl and I am now in reference chapter, and this topic confuses me. I understand the concept of reference since I know C programming too. In the book I am reading says:
"Not only can you dereference a simple variable name, you can also dereference the contents of a BLOCK. Anywhere you'd put an alphanumeric identifier as part of a variable or subroutine name, you can replace the identifier with a BLOCK returning a reference of the correct type."
I need an example on this part- "anywhere you'd put an alphanumerc identifier as part of a variable.... you can replace the identifier with a block" - exactly how would that happen?
and this example too:
&{ $dispatch{$index} }(1, 2, 3);
Can somebody explain that code.
The quoted paragraph is saying that you're not limited to doing
my $handler = $displatch{$type} or die; # Arbitrary code
my $ref = $handler->(); # Arbitrary code
my #a = #$ref;
You can also do
my #a = #{ my $handler = $displatch{$type} or die; $handler->() };
Same goes for other dereferences.
$BLOCK
$BLOCK[ ... ]
$BLOCK{ ... }
#BLOCK
#BLOCK[ ... ]
#BLOCK{ ... }
%BLOCK
&BLOCK
&BLOCK( ... )
*BLOCK
$index contains the name of a hash key. %dispatch is the hash with said key. The value associated with that key is a subroutine reference, which &{} dereferences. It's invoked with 1, 2, 3 as its arguments.
This is a fine enough example, although I would generally write:
$dispatch{$index}->(1, 2, 3)
sub sample_function1 {
...
}
sub sample_function2 {
...
}
%dispatch = ( 'f1' => \&sample_function1,
'f2' => \&sample_function2 );
$index = <STDIN>;
chomp $index;
&{ $dispatch{$index} }(1, 2, 3);
If the user enters f1 this will call sample_function1(1, 2, 3), if he enters f2 it will call sample_function2(1, 2, 3).
What the documentation is explaining is that you since you can write sample_function1(1, 2, 3), you can replace the function name with a block containing code that returns a function reference.
Take a look at the File::Find. You may have even used that before. It's one of the first Perl modules that many Perl programmers ever use.
The find command takes two arguments:
The second (we'll start with the simple one) is a list of directories I want to search.
The first argument is a bit trickier -- it's an actual subroutine my find command will use. The find command uses that subroutine to determine if a particular element in my directory tree matches the criteria I'm looking for. What find does is go through each and every element of my directory tree and passes that element to my subroutine. It's up to my subroutine to check the element to see if it passes muster.
Let's say I want to find all files in my directory that have the suffix of .txt. In Unix, I could do this:
$ find $directory -type f -name "*.txt"
In Perl, I create a subroutine called wanted. The find command will pass to my wanted subroutine an element in my directory via the $_ Perl variable. I can then test that element to see if it's a file that has a .txt suffix:
sub wanted {
return unless -f; #Return unless $_ is a file
return unless /\.txt$/; #Return unless that file has a `.txt` suffix
print "$Find::File::name\n"; #It's a file that ends with .txt. Print it.
}
Now, all I have to do is get my wanted subroutine as the first parameter of my find command:
find ( \&wanted, $directory );
That's all there is to it. A real life example that you will (if you haven't already) run into really soon. In C programming parlance, the wanted subroutine would be called a Callback routine.