Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Tie::File Write Problem

by packetstormer (Monk)
on Nov 17, 2011 at 19:19 UTC ( #938670=perlquestion: print w/replies, xml ) Need Help??
packetstormer has asked for the wisdom of the Perl Monks concerning the following question:


I am having a strange problem writing to a file with Tie::File. The code is below. The output to screen writes fine but the actual file isn't change. Its not permissions as I can write to the file fine if I don't split the line. I wonder if there is a fundamental problem with splitting the tie array and editing an element in that?

#!/usr/bin/perl use strict; use CGI; use Tie::File; my $query = new CGI; #my $file = $query->param('filename'); my $file = '/tmp/test.csv'; my @lines; print $query->header(); tie @lines, 'Tie::File', $file or die "No file found to work with."; print "We got $#lines lines in this file"; foreach my $i(@lines) { my @tmp = split (",",$i); if($tmp[6] eq "6 Elm") {$tmp[6] = 'XXXXX'} print "$i\n"; } untie @lines;

Does anything look obvious?

Replies are listed 'Best First'.
Re: Tie::File Write Problem
by toolic (Bishop) on Nov 17, 2011 at 19:30 UTC
    After you tied the file to the @lines array, you never make a modification to the @lines array. See Tie::File.
    tie @lines, 'Tie::File', $file or die "No file found to work with."; $lines[0] = 'foo'; # this should change the tied file
      That's my confusion, doesn't this line change the element in the line?
      if($tmp[6] eq "6 Elm") {$tmp[6] = 'XXXXX'}
      I am splitting each line up based on the commas in the line and changing that element
        That line does not change the @lines array or the tied file. That just changes the @tmp array. Tip #4 from Basic debugging checklist:
        use Data::Dumper; print Dumper(\@tmp); print Dumper(\@lines);

        @tmp is a completely separate variable that is not tied to the file. The split copies the data. You would have to add the following inside the foreach-loop to change the file as you intented:

        $i= join(',',@tmp);

        Note that even this works only because $i actually is an alias to the data in @lines and not a copy (this is magic done by the foreach loop)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://938670]
Approved by toolic
[Corion]: "flag problem" to me sounds like "contains UTF-8 bytes but was never properly decoded to an UTF-8 string"
[LanX]: not my code ...
[choroba]: yeah, sounds like one of the strings is not flagged as UTF-8
[choroba]: which usually means its input wasn't handled correctly
[Corion]: choroba: Yeah, I think that would be the good solution
[LanX]: I suspect the first string which comes from the DB ...
[LanX]: ... but this part is already in production for a year now
[Corion]: LanX: The "good" approach here would be to use the appropriate DBI parameters to make the driver decode strings properly. But that will have a ripple-on effect of messing up all the places where manual decoding happens ;)
[LanX]: which means albeit being broken UTF8 it'll be handled correctly
[LanX]: and the problem only occurs since we changed the emails to base64

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (11)
As of 2017-01-16 13:57 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (150 votes). Check out past polls.