qq:i {} is just like qq{} except that when it interpolates variables,
those which are undefined are preserved literally.
its purpose would be to support the construction of strings for
subsequent eval'g, particularly where you have one or more variables
to interpolate, so you cant just use q{}, but you also have lots of
other vars that yould prefer not to backwhack.
its like closures on my vars, only differnt.
for $memberfn (qw( foo bar belch )) {
# forgive errant? p5 syntax - I dont do this often
*{__PACKAGE__}::${memberfn} = eval sub qq:i {
my $self = shift; # $self is
undef when interpolated, so preserved
$self->{member}{$memberfn} = 1; # $self preserved, $memberfn
interpolated
... # presumably something useful (but not in this example)
}
or die "badness happend";
}
Or maybe this is all superseded by p6 features, Im just cant keep up.
(as you can tell from the p5 code)
Theres also some room for unholiness tho;
my @args = @{$template{args}};
my $body = $template{body};
eval sub qq:i{
my ($self, @args) = @_;
$body;
}
Please explain what you want it to do with @args there.
Juerd
Bang! :-)
The problem with "interpolate if you can or leave it alone for
later" is that when later comes around you're in a quandry.
Is the string "$var" that is in the final result there because
it was "$var" in the original and couldn't be interpolated,
or was it a $foo that had its value of "$var" injected into
its place?
The "maybe do it now, finish up later what wasn't done the
first round" approach runs the risk of double interpolation.
(Or single interpolation, or non-interpolation, whichever
it happened to roll on the dice.) If you're Randal Schwartz
discovering a
s/Old Macdonald/$had a $farm/eieio
accidental feature, that can be useful; but for mere portals,
it is just a bug waiting to surface.
--
Eeeew. Probably going to shoot this down. But let's see where you're
going with it :-)
> for $memberfn (qw( foo bar belch )) {
> # forgive errant? p5 syntax - I dont do this often
> *{__PACKAGE__}::${memberfn} = eval sub qq:i {
>
> my $self = shift; # $self is undef when interpolated, so preserved
> $self->{member}{$memberfn} = 1; # $self preserved, $memberfn interpolated
> ... # presumably something useful (but not in this example)
> }
> or die "badness happend";
> }
Yeah, well, you could try to write qq:i, but it's not going in the
"standard dialect" any time soon.
I think a good solution to this problem would be to find an uncommon
character (well, this is Perl, so that doesn't really exist... but...
you can find one), and call that the "interpolate" character. Then you
could do (Perl6-land now):
for <foo bar belch> -> $memberfn {
&::($?PACKAGE)::($memberfn) := eval q:h:b('`')/END/;
method ($self:) {
$.member.{`{$memberfn}} = 1;
# ...
}
END
err die "badness"
}
Still not very pretty, but symbol table manipulation was never pretty.
Anyway, the idea is that `{foo} evaluates foo and interpolates it.
We could make that a standard parameter to :b (was it :b to interpolate
{}? I don't remember), or we could make it a module. Whatever, I'd use
it.
Luke
> since the qq:X family has recently come up, Id like to suggest another.
>
> qq:i {} is just like qq{} except that when it interpolates variables,
> those which are undefined are preserved literally.
So then when doing maintenance on some code I can break it by
introducing a new variable with a name that hasn't been used anywhere
else -- because there was some code relying on that variable _not_ being
defined?
Ouch.
Smylers
>The problem with "interpolate if you can or leave it alone for
>later" is that when later comes around you're in a quandry.
>Is the string "$var" that is in the final result there because
>it was "$var" in the original and couldn't be interpolated,
>or was it a $foo that had its value of "$var" injected into
>its place?
>
>The "maybe do it now, finish up later what wasn't done the
>first round" approach runs the risk of double interpolation.
>(Or single interpolation, or non-interpolation, whichever
>it happened to roll on the dice.) If you're Randal Schwartz
>discovering a
>
> s/Old Macdonald/$had a $farm/eieio
>
>accidental feature, that can be useful; but for mere portals,
>it is just a bug waiting to surface.
>
>
Maybe this should be the default behavior.
my $nameRight = "name";
my $nameWrong = "other name";
print "$nameRight != $name_wrong\n";
name != $name_wrong
I wonder where my mistake is?
This looks like a decent win for PEBKAC errors. Maybe this should go on
by default if the "I need help" flag is turned on.
OTOH, I don't have much use for the original proposal because I also
want to be able to defer interpolation of variables that DO exist, like $!.
I like the idea of defining a secondary interpolation character, or
perhaps a secondary escape character.
my $name = "defined now, but it will change later";
my $output_text = <<EOF:esc('`');
$template_header
`$name
$template_footer
EOF
=Austin
> qq:i {} is just like qq{} except that when it interpolates variables,
> those which are undefined are preserved literally.
I think surprise might be a problem. E.g.
my $index = 0;
eval qq:i {
my @array = A .. Z;
sub example {
for my $index (0 .. $#array) {
#stuff
}
}
}
Common variable names like $i, $index, $element etc might end up being
replaced by mistake in the qq:i {}. Can't see it being acceptable in
strict code.
Interesting idea except for the flaw.
Jonathan Paton
I think we almost have something like this already. Looking at the
updated Synopsis 2, I think you can use closure interpolation with
single quotes like this:
my $name = 'vars';
my $code = q:c[ my @{$name} = ($a, $b, $c); ];
# prints " my @vars = ($a, $b, $c); ";
say $code;
The problem is that you also need {}'s for subroutines and other
things. But the underlying problem is that using another character to
interpolate doesn't get you anywhere because then you can't use that
in your code.
So... maybe we can pass a parameter saying what we want to use to interpolate?
my $name = 'add';
my $code = q:c<«>[
sub «$name» ($left, $right) {
return $left + $right;
}
];
# prints "
# sub add ($left, $right) {
# return $left + $right;
# }
# "
Where you could whatever you wanted instead of «».
--
matt diephouse
http://matt.diephouse.com
Or maybe we just stick with what we already allow:
my $name = 'add';
my $code = q[
sub \qq[$name] ($left, $right) {
return $left + $right;
}
];
After all, that's why we put \q interpolation into '' in the first place.
Larry
I missed that. Thanks.
Ahh yes. Silly me, thinking there was something without a nice
solution. This is Perl!
Luke