in reply to set proto string

That's not how Perl (or many other programming languages) work. The variable is filled at the time the assignment is done.

What you probably want to achieve is that $proto2 is a reference to @a? Something like you've already done with $proto1.

But when you assign $proto2, you are generating a string (a temporary scalar, technically) that is assigned to $proto2. $proto2 has no concept that its new value is derived from @a. To make $proto2 behave more like you want it to (though not exactly), you can make it a reference to an anonymous subroutine:

#!/usr/bin/env perl use v5.38; use strict; use warnings; my @a; my $proto2 = sub { return "@{\@a} 3 4"; }; @a = (1, 2); print $proto2->(), "\n"; # prints "1 2 3 4"

To make this more in line with your requirements (=evaluating the stuff on access), you can make $proto2 a tied variable. In this case, you also need to make @a accessible from other packages by declaring it "our" instead of "my". Basically, $proto2 is tied to a class (package) and runs its own logic:

#!/usr/bin/env perl use v5.38; use strict; use warnings; package vincentaxhe; sub TIESCALAR { bless \my $self, shift } sub STORE { ${ $_[0] } = $_[1] } # remember the postfix string sub FETCH { "@{\@main::a} " . ${ my $self = shift } }; package main; our @a; tie my $proto2, 'vincentaxhe'; $proto2 = '3 4'; @a = (1, 2); print $proto2, "\n"; # prints 1 2 3 4 @a = (22, 23, 24); print $proto2, "\n"; # prints 22 23 24 3 4 $proto2 = 'Hello World'; print $proto2, "\n"; # prints 22 23 24 Hello World

There are probably smarter ways to bind @a to $proto2 in a tied variable than hardcoding it. But it's Saturday and i need to go shopping for some food (shops are closed tomorrow), so i got limited time to spend on this.

PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP
Also check out my sisters artwork and my weekly webcomics

Replies are listed 'Best First'.
Re^2: set proto string
by LanX (Saint) on Aug 17, 2024 at 16:45 UTC
    > There are probably smarter ways to bind @a to $proto2 in a tied variable than hardcoding it.

    First of all using a closure variable my @a is also possible in your example if it's in the same scope like sub FETCH

    Now provided that the package is an extra file, hence foreign scope, you can still pass arguments to the tie command, like a ref to \@a.

    See tie VARIABLE,CLASSNAME,LIST

    > Any additional arguments in the LIST are passed to the appropriate constructor method for that class--meaning TIESCALAR() , ...

    Edit

    But for flexibility and reusability I'd rather pass a coderef in LIST which acts as FETCH and returns the string.

    FETCH would access the coderef as an attribute of $self

    Hence for a package MyFetch tie $magic, MyFetch, sub { "@a 1,2" } would do and the numbers of closure variables would be totally free.

    That's the beauty of functional programming. :)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

      Oh wow, it didn't even cross my mind that i could give the coderef to the tied variable.

      That only goes to show that i haven't played with tie for a long time and really should take some time to refresh my knowledge in that area. I actually had to look up a small tutorial on it just to write my very basic example.

      Thanks!

      PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP
      Also check out my sisters artwork and my weekly webcomics