Click to See Complete Forum and Search --> : Escaping package separator in string?
Scriptage
12-14-2008, 03:13 PM
If one was to modify the symbol table thus:
*{$variableName} = "This is Carl's string!";
PERL thinks that "Carl" is a package due to its backwards compatible " ' " package separator and thus ignores everything before " ' ". Does anybody know of a way to escape the separator or prevent PERL from thinking it's a package?
Any help would be greatly appreciated.
Regards
Carl
Sixtease
12-15-2008, 01:42 AM
This does not sound correct. The single quote in the right hand side string is just a literal single quote. If you had "this is $Carl's string", with a dollar (or @ or %), then it would be considered the same as "this is $Carl::s string".
If that is the matter, then you can either put braces around the variable name: "this is ${Carl}'s string" or just escape the single quote with a backslash: "this is $Carl\'s string".
However, since you don't have a sigil on the RHS, I guess your problem is on the left hand side. What exactly are you expecting this *{$VariableName} to mean? If you just need to assign to variable of the name $VariableName, then I think this is a better way:no strict 'refs';
${ $VariableName } = "this is Carl's string";
use strict;
But why do you need to access a variable by its dynamically retrieved name? Wouldn't it be better to use a hash?my %vars = (
foo => 'foo value',
bar => 'bar value',
);
...
$VariableName = 'foo';
$vars{ $VariableName } = "this is Carl's string";
Scriptage
12-16-2008, 06:54 AM
Hi Sixtease,
Thanks for the reply. That was the problem "${$VariableName}" does the trick, however, I was over thinking the entire thing and ended up using a hash instead as you suggested.
I wanted properties for a class similar to C# so I defined a hash of property names and default values then iterated through them defining a new getter / setter subroutine with a closure but thinking about it the closure is absolutely pointless. The final implementation:
#!/usr/bin/perl
use strict;
my $person = Person->new();
$person->firstName("Carl");
$person->lastName("Bates");
$person->comments(qq{
Carl's comments here.
});
$person->display();
package Person;
sub new{
my $class = shift;
my $self = {};
my %properties = (
firstName => undef,
lastName => undef,
age => 22,
comments => undef,
);
foreach my $property(keys %properties){
{
no strict 'refs';
*{$property} = sub{
$self = shift;
if(@_){
$properties{$property} = shift;
}
return $properties{$property};
}
}
}
bless($self, $class);
}
sub display{
my $self = shift;
print $self->firstName . " " . $self->lastName . " is " . $self->age . "\n" . $self->comments;
}
1
Sixtease
12-16-2008, 08:34 AM
The only little ugliness I see is that you define the package subroutines upon creation of every instance. If you want to dynamically create accessor methods from the properties defined, then I'd do it in the import method, which is called upon "use" (see perlmod).
Even better, don't reinvent the wheel and use Class::Std (http://search.cpan.org/~dmuey/Class-Std-0.0.9/lib/Class/Std.pm). Don't let the verbosity of the documentation discourage you, it's fairly simple to use.
Scriptage
12-24-2008, 06:09 AM
Thanks but it's kind of like using a shotgun to kill a fly. I wasn't planning on having more than one instance of the class to be honest but it is something to bear in mind.
Thanks for your help bud.