Re: Evaluate variable while using
by hippo (Bishop) on Oct 21, 2022 at 11:34 UTC
|
I'm not sure how to achieve this.
The How depends mostly on the Why - and you have not explained that. This is probably an XY Problem.
One solution is a closure.
#!/usr/bin/env perl
use strict;
use warnings;
my $x;
sub greeting {
my $str = 'Hello ' . $x;
print $str . "\n";
}
$x = 'Kevin';
greeting ();
$x = 'chickenman';
greeting ();
| [reply] [Watch: Dir/Any] [d/l] |
Re: Evaluate variable while using
by bliako (Monsignor) on Oct 21, 2022 at 13:22 UTC
|
If you are prepared to replace the string "Hello ".$a; with a function which constructs the string on-the-fly then:
my $x;
my $str = sub { "hello ".${\$x} };
$x = 'kevin';
print $str->();
$x = 'chickenman';
print $str->();
This resembles hippo's Re: Evaluate variable while using (which is simpler as it achieves the same without the use of refs).
A more complete and acceptable solution would be to use an OO approach where a class holds the data and offers methods to update and print the data and any subsequent strings you may want to produce, i.e. $executable. This is a textbook usage for OO which keeps its data and its methods in their castle with crocodiles all around.
{package XYZ;
sub new {
my $class = shift;
my $self = {
homedir => '<empty>'
};
return bless $self => $class
}
sub homedir {
my $self = $_[0];
if( defined $_[1] ){ $self->{homedir} = $_[1] }
return $self->{homedir}
}
sub executable { my $self = $_[0]; return $self->homedir()."/xyy/abc"
+}
1;
}
my $xyz = new XYZ();
$xyz->homedir("ahah");
print "homedir: ".$xyz->homedir()."\n";
print "exec: ".$xyz->executable()."\n";
# note, when dealing with paths use File::Spec->catdir()
That's probably a good approach.
bw, bliako | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Evaluate variable while using
by choroba (Cardinal) on Oct 21, 2022 at 12:22 UTC
|
my $str = "Hello ".$a;
populates $str using the current value of $a. $str doesn't remember $a was used to construct it, so changing $a doesn't have any influence on its value.
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Evaluate variable while using
by bliako (Monsignor) on Oct 21, 2022 at 12:42 UTC
|
my $hello = sub { 'hello '.$_[0] };
print "kevin"->$hello;
# or
my $x = 'kevin';
print $x->$hello;
credit to Discipulus's latest well-spaced JAPH
bw, bliako | [reply] [Watch: Dir/Any] [d/l] |
Re: Evaluate variable while using
by tobyink (Canon) on Oct 21, 2022 at 12:42 UTC
|
use strict;
use warnings;
use String::Interpolate::Delayed;
my $a = '';
my $str = delayed "Hello $a";
$a = 'Kevin';
print $str;
It requires UNIVERSAL::ref though, which is broken on versions of Perl above 5.24.x. (There's a patch to fix it on the UNIVERSAL::ref issue tracker.)
| [reply] [Watch: Dir/Any] [d/l] |
Re: Evaluate variable while using
by GrandFather (Saint) on Oct 21, 2022 at 11:35 UTC
|
Why?
If you tell us something about the context of the problem we will be able to help, but we can't reliably read minds and that slows us down when it comes to guessing what you are actually trying to achieve.
Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
| [reply] [Watch: Dir/Any] |
Re: Evaluate variable while using
by BillKSmith (Monsignor) on Oct 21, 2022 at 15:55 UTC
|
If you have several variables which require this behavior, it is convenient to write a function (str_maker) which generates the closures for you.
use strict;
use warnings;
use feature 'say';
sub str_maker{
my $fixed = $_[0];
my $dynamic = \$_[1];
my $closure = sub{
return $fixed . ', ' . $$dynamic;
};
return $closure;
}
my ($aa, $bb);
my $static;
$static = 'Hello';
my $str1 = str_maker($static, $aa);
$static = 'Greetings';
my $str2 = str_maker($static, $bb);
$aa = 'Kevin';
say &$str1; # Hello, Kevin
$bb = 'World';
say &$str2; # Greetings World
$aa = 'Bill';
say &$str1; # Hello, Bill
$bb = 'Aliens';
say &$str2; # Greetings, Aliens
Minor point: $a and $b are poor choices for variable names because they may clash with variables of the same name used in sort. I used $aa and $bb instead.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Evaluate variable while using
by afoken (Chancellor) on Oct 21, 2022 at 16:22 UTC
|
So many ways to re-invent templates ... - if you need this in more than one place, consider using one of the template engines from CPAN, like Template or Text::Template instead of using one of those ad-hoc solutions.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
| [reply] [Watch: Dir/Any] |
Re: Evaluate variable while using
by Fletch (Bishop) on Oct 21, 2022 at 11:51 UTC
|
Seconding (Thirding?) the vagueness and XY problem complaints. Without more context no one's going to be able to make maybe vague suggestions like a magic tied scalar, or maybe something like Template / TT2 is what you're after, or . . . .
The cake is a lie.
The cake is a lie.
The cake is a lie.
| [reply] [Watch: Dir/Any] |
Re: Evaluate variable while using
by sectokia (Pilgrim) on Oct 21, 2022 at 13:36 UTC
|
If your intention is to build up strings that contain variables, and then later interpolate that string with the values of the variables, one way would be like this:
my $a = '';
my $str = 'Hello $a';
$a = 'Kevin';
print eval qq{"$str"}
| [reply] [Watch: Dir/Any] [d/l] |
|
Thank you, that's exactly what i was looking for.
| [reply] [Watch: Dir/Any] |
|
Thank you, that's exactly what i was looking for.
Be aware that stringy eval has some serious security implications: if you give it anything based on user input, you'll have built yourself a giant security hole, as it will happily execute any arbitrary code. I strongly recommend you use one of the many other suggestions in this thread instead.
| [reply] [Watch: Dir/Any] |
Re: Evaluate variable while using
by jo37 (Deacon) on Oct 21, 2022 at 18:23 UTC
|
Not a serious proposal, but another example of TIMTOWTDI:
You may create an array that holds an alias to $a as the second element and interpolate it into a string.
#!/usr/bin/perl
use v5.16;
use warnings;
my $a = '';
local our @str;
sub {*str = \@_}->('Hello', $a);
$a = 'Kevin';
say "@str";
Greetings, -jo
$gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
| [reply] [Watch: Dir/Any] [d/l] [select] |