embedding Variable

M

Mike Solomon

If I write the following code

my $test = "test";

my $output "my test = $test\n";

$test = "NEW TEST";

print $output;

then I will get : my test = test";

is there any way of writing this so as I change $test , $output also changes

Sorry if this a stupid question


Regards Mike
 
C

Cognition Peon

#!/usr/bin/perl -w

my $test = "test";
my $output = output();
print $output;
$test = "NEW TEST";
$output = output();
print $output;

sub output {

return "my test = $test\n";
}


9:37pm, IP packets from Mike Solomon delivered:
 
T

Tintin

Mike Solomon said:
If I write the following code

my $test = "test";

my $output "my test = $test\n";

$test = "NEW TEST";

print $output;

then I will get : my test = test";

is there any way of writing this so as I change $test , $output also changes

Sorry if this a stupid question

My question would be to ask what you are trying to acheive.

I'm almost certain that once we know the problem, there will be a much
better solution/approach to take.
 
M

Marco

Mike said:
If I write the following code

my $test = "test";
my $output = "my test = $test\n";
$test = "NEW TEST";
print $output;

then I will get : my test = test";

is there any way of writing this so as I change $test , $output also
changes

Hi Mike,
$output needs to be something that dynamically binds
to the latest value of $test every time. Try this:

my $test = "test";
my $output = sub { "my test = $test\n" };
$test = "NEW TEST";
print $output->(); # or print &$output;

In line 2, $output is initialized to point to an
anonymous subroutine that will re-evaluate $test
every time it's called. Technically, this is known
as a closure.

Line 4 also differs because I now have to dereference
$output to make it behave like the subroutine it
points to.

Marco
 
J

Jay Tilton

: If I write the following code
:
: my $test = "test";
:
: my $output "my test = $test\n";
:
: $test = "NEW TEST";
:
: print $output;
:
: then I will get : my test = test";
:
: is there any way of writing this so as I change $test , $output also changes

You could do that with a tied scalar.

#!perl
use warnings;
use strict;

package MyString;
sub TIESCALAR {
my $class = shift;
my($fmt, @srefs) = @_;
bless sub{ sprintf $fmt, map $$_, @srefs }, $class;
}
sub FETCH{ shift->() }

package main;
tie my($output), 'MyString', "my test = %s", \(my $test);
$test = 'test';
print "$output\n";
$test = $test = "NEW TEST";
print "$output\n";

tie $output, 'MyString', "My %s has %s.\n", \(my($pet, $pest));
($pet, $pest) = ('dog', 'fleas');
print $output;
($pet, $pest) = ('program', 'bugs');
print $output;
 
T

Tad McClellan

Mike Solomon said:
If I write the following code
my $output "my test = $test\n";
then I will get


A syntax error.



Do not re-type Perl code
Use copy/paste or your editor's "import" function rather than
attempting to type in your code. If you make a typo you will get
followups about your typos instead of about the question you are
trying to get answered.


Like this one.
 
M

Mike Solomon

As Tad pointed out should be my $output = "my test = $test\n";
A syntax error.



Do not re-type Perl code
Use copy/paste or your editor's "import" function rather than
attempting to type in your code. If you make a typo you will get
followups about your typos instead of about the question you are
trying to get answered.


Like this one.

Point taken Tad

Thanks for the help everyone.

I think I will go the sub routine route unless any one else has any bright
ideas
 
N

nobull

Cognition Peon said:
9:37pm, IP packets from Mike Solomon delivered:
#!/usr/bin/perl -w

my $test = "test";
my $output = output();
print $output;
$test = "NEW TEST";
$output = output();
print $output;

sub output {

return "my test = $test\n";
}

Usually one would simply use an _anon_ sub.

my $test = "test";
my $output = sub { "my test = $test\n" };
print $output->();
$test = "NEW TEST";
print $output->();

But if you want $output to look like an ordinary scalar you could use
or a tied scalar or an object that overloads "" depending on when you
want the subtitution to occur...

use Tie::OneOff;
my $test = "test";
tie my $output, 'Tie::OneOff', sub { "my test = $test\n" };
print $output;
my $copy_output = $output; # substition occurs here
$test = "NEW TEST";
print $output;
print $copy_output; # prints "my test = test"


# For reasons I don't understand the current release (0.1) of
# String::Interpolate has stopped working - so don't use it!
use String::Interpolate;
my $test = "test";
my $output = String::Interpolate->new( { test => \$test}, 'my test =
$test\n' );
print $output;
my $copy_output = $output; # substition does not occur here
$test = "NEW TEST";
print $output;
print $copy_output; # prints "my test = NEW TEST"
 
N

nobull

package MyString;
sub TIESCALAR {
my $class = shift;
my($fmt, @srefs) = @_;
bless sub{ sprintf $fmt, map $$_, @srefs }, $class;
}
sub FETCH{ shift->() }

package main;
tie my($output), 'MyString', "my test = %s", \(my $test);

I really think you shouldn't have to declare a new package just to
make one-off tied variable...

use Tie::OneOff;
my $test;
tie my $output, 'Tie::OneOff', sub {
sprintf "my test = %s", $test;
};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top