I've been tinkering with lvalue subroutines.
Initially, they looked like a nice idea (from a users perspective at least), but now I'm not so sure :-)
I'm attempting to create a package that allows copying one field from a line to another field; basically:
A simple case (taken from one of merlyn's posts) works:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
{
package Foo;
sub new {
my $class = shift;
return bless( { field => "ABCDEF" }, $class );
}
sub field : lvalue {
my $self = shift;
$self->{'field'};
}
}
my $f = Foo->new();
print $f->field, "\n";
$f->field = reverse $f->field;
print $f->field, "\n";
print Dumper $f;
Output:
ABCDEF
FEDCBA
$VAR1 = bless( {
'field' => 'FEDCBA'
}, 'Foo' );
My code, however only appears to work for the first line of input. The object is being updated, but the substring doesn't appear to return the correct value.
Field positions and lengths are being stored in the module and looked up.
Input:
00001AAAAA
00002AAAAA
00003AAAAA
00004AAAAA
00005AAAAA
00006AAAAA
00007AAAAA
00008AAAAA
00009AAAAA
00010AAAAA
Code:
#!/usr/bin/perl
use strict;
use warnings;
use String;
use Data::Dumper;
my $str = String->new();
while (<>) {
$str->line() = $_;
print "BEFORE: ";
print Dumper $str;
print "A: ", $str->field_int( "a" ), "\n";
print "B: ", $str->field_int( "b" ), "\n";
$str->field_int( "a" ) = $str->field_int( "b" );
print "AFTER: ";
print Dumper $str;
print "LINE: ", $str->line(), "\n" x4;
}
Module:
package String;
use strict;
use warnings;
sub new {
my $class = shift;
my %arg = @_;
my $ddl = { a => { start => 0,
length => 5,
},
b => { start => 5,
length => 5,
},
n => { start => 10,
length => 1,
},
};
my $self = { ddl => $ddl,
line => undef,
};
bless $self, $class;
}
sub line : lvalue {
my $self = shift;
my $line = shift;
$self->{'line'};
}
sub field_start {
my $self = shift;
my $field = shift;
return $self->{'ddl'}{$field}{'start'};
}
sub field_length {
my $self = shift;
my $field = shift;
return $self->{'ddl'}{$field}{'length'};
}
sub field_int : lvalue {
my $self = shift;
my $field = shift;
print "SUBSTR: ", substr($self->{'line'}, $self->field_start($field)
+, $self->field_length($field)), "\n";
substr($self->{'line'}, $self->field_start($field), $self->field_len
+gth($field) );
}
1;
Output:
BEFORE: $VAR1 = bless( {
'line' => '00001AAAAA
',
'ddl' => {
'n' => {
'length' => 1,
'start' => 10
},
'a' => {
'length' => 5,
'start' => 0
},
'b' => {
'length' => 5,
'start' => 5
}
}
}, 'String' );
SUBSTR: 00001
A: 00001
SUBSTR: AAAAA
B: AAAAA
SUBSTR: AAAAA
SUBSTR: 00001
AFTER: $VAR1 = bless( {
'line' => 'AAAAAAAAAA
',
'ddl' => {
'n' => {
'length' => 1,
'start' => 10
},
'a' => {
'length' => 5,
'start' => 0
},
'b' => {
'length' => 5,
'start' => 5
}
}
}, 'String' );
LINE: AAAAAAAAAA
BEFORE: $VAR1 = bless( {
'line' => '00002AAAAA
',
'ddl' => {
'n' => {
'length' => 1,
'start' => 10
},
'a' => {
'length' => 5,
'start' => 0
},
'b' => {
'length' => 5,
'start' => 5
}
}
}, 'String' );
SUBSTR: 00002
A: 00002
SUBSTR: AAAAA
B: 00002
SUBSTR: AAAAA
SUBSTR: 00002
AFTER: $VAR1 = bless( {
'line' => '00002AAAAA
',
'ddl' => {
'n' => {
'length' => 1,
'start' => 10
},
'a' => {
'length' => 5,
'start' => 0
},
'b' => {
'length' => 5,
'start' => 5
}
}
}, 'String' );
LINE: 00002AAAAA
etc.
Notice that The last LINE: is "00002AAAAA" I'm expecting "AAAAAAAAAA", as with the first piece of output.
What is going wrong? Have I missed something obvious?
Cheers,
BazB
If the information in this post is inaccurate, or just plain wrong, don't just downvote - please post explaining what's wrong.
That way everyone learns.