Reputation: 2130
I need to initialize a string with a fixed text concatenated to a variable like this:
my $id = 0;
my $text ="This is an example, id: ".$id."\n";
Now, in a imaginay loop for 0->9, I want to modify only the $id
value without changing the fixed text.
I guessed that using references should work like this way
for($i = 0; $i < 9; $i++) {
my $rid = \$id;
${$rid}++;
print $text;
}
Wanted output is
This is an example, id: 0
This is an example, id: 1
This is an example, id: 2
and so on...but it's not working.
Am I misunderstanding referencing system?
Upvotes: 0
Views: 99
Reputation: 118128
You seem to be confused about references. Maybe you are thinking thinking of the following C pointer scenario:
char text[] = "This is a test xx\n";
char *cursor = text + 15;
*cursor = ' 1';
I don't know what thought process can bring about the impression that once you interpolate the contents of $id
into my $x = "Test string $id"
, you can change the value of the interpolated string by changing the value of $id
.
As I said, you really are confused.
Now, if you want a subroutine someplace to be able to format some output without embedding in the subroutine the output format, you can pass as one of the arguments to the subroutine a message formatter as in:
my $formatter = sub { sprintf 'The error code is %d', $_[0] };
forbnicate([qw(this that and the other)], $formatter);
sub frobnicate {
my $args = shift;
my $formatter = shift;
# ...
for my $i (0 .. 9) {
print $formatter->($i), "\n";
}
return;
}
This is bound to get tedious, so you can basically have a package of formatters, and let subs use whatever formatters they need:
package My::Formatters;
sub error_code {
my $class = shift;
return sprintf 'The error code is %d', $_[0];
}
In the main script:
use My::Formatters;
for my $i (0 .. 9) {
My::Formatters->error_code($i);
}
Upvotes: 1
Reputation: 1560
As Sinan pointed out there is an easier way to do this. If you want to keep the $text
string separate for maintainability and/or reuse, you may also consider using sprintf
, e.g.:
my $id = 0;
my $max_id = 9;
my $text = "This is an example, id: %d\n";
for (my $i = $id; $i < $max_id; $i++) {
print sprintf($text, $i+1);
}
Upvotes: 1
Reputation: 5348
You are missunderstanding the reference system.
with
my $id = 0;
my $text ="This is an example, id: ".$id."\n";
The text is concatinated with the value of id at that point, in this case 0. This text loses all connection with the varable $id. Then in the loop
for($i = 0; $i < 9; $i++) {
my $rid = \$id;
${$rid}++;
print $text;
}
You are incrementing the $id
variable using $rid
( which in becomes another name for $id
at my $rid = \$id;
but this will have no affect on the text as it has no reference to the variable $id
.
The cleanest way of doing what your trying to do is to use a closure
my $id = 0;
my $textfunc = sub { return "This is an example, id: ".$id."\n" };
then in your loop do
for($i = 0; $i < 9; $i++) {
$id++;
print $textfunc->();
}
Upvotes: 3