Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Evaluate variable while using

by chickenman (Novice)
on Oct 21, 2022 at 11:20 UTC ( [id://11147561]=perlquestion: print w/replies, xml ) Need Help??

chickenman has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

i'm facing a Problem and i'm not able to google the answer. The Problem is that i'm even not sure about what to search..

Let me try to explain. I've a variable which contains another variable which value changes after it has been stored in the second variable.

E.g.
my $a = ''; my $str = "Hello ".$a; $a = 'Kevin'; print $str;
The expected output is

Hello Kevin

I'm not sure how to achieve this.

Thank you in advance.

### EDIT ####

It is only about readability.

I've created a Perl Package which delivers all default values for the Program context

Some of these values are relaing on variables which will be updated during runtime.

Like my $executable = "$homedir/bin/abc"; And $homedir will be found within the perl Code.

Of course i could move this variable into a subroutine and read it once $homedir has been set.

But in the same context there are variables which have been changed and i don't won't to overwrite them again.

The only solution i can think of is to split the static variables and the dynamic ones into different subroutines.

I thought there might be an option to evaluate the variable value when accessing it for the first time.

Replies are listed 'Best First'.
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 ();

    🦛

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

Re: Evaluate variable while using
by choroba (Cardinal) on Oct 21, 2022 at 12:22 UTC
    The problem is that
    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]
Re: Evaluate variable while using
by bliako (Monsignor) on Oct 21, 2022 at 12:42 UTC
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.)

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
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.

    Bill
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". ;-)
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.

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"}
      Thank you, that's exactly what i was looking for.
        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.

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$

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11147561]
Approved by marto
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (4)
As of 2024-03-28 18:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found