Skip Menu |

This queue is for tickets about the Data-Serializer CPAN distribution.

Report information
The Basics
Id: 23901
Status: resolved
Estimated: 15 min
Worked: 15 min
Priority: 0/
Queue: Data-Serializer

People
Owner: neil [...] neely.cx
Requestors: jamie.lentin [...] bbc.co.uk
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: Data::Serializer::Retrieve doesn't slurp files
If you try to use retrieve to read a file that contains a newline, the deserialization won't work. When retrieve() reads a file into $input, it will stop at any \n in the file since $/ is still defined. A "local $/" at the beginning of the function should sort it. Or alternatively using File::Slurp or something. Cheers for all your work!
CC: jamie.lentin [...] bbc.co.uk
Subject: Re: [rt.cpan.org #23901] Data::Serializer::Retrieve doesn't slurp files
Date: Fri, 2 Mar 2007 13:14:32 -0700
To: bug-Data-Serializer [...] rt.cpan.org
From: Neil Neely <neil [...] frii.com>
I don't normally manipulate $/ so wanted to give your report some proper study before determining the correct course of action - unfortunately nearly 4 months snuck in between that thought and my first serious attempt to get to the bottom of what you reported. When I tried to reproduce the error you were reporting, I could not actually do so under normal operations. No matter how many newlines one put at the end of a serialized data structure, it would deserialize just fine. What I was able to determine was that if you undefine $/ in the global context I could reproduce what you were describing. Looking at perldoc perlvar, it has this to say on the subject: [snip] You should be very careful when modifying the default values of most special variables described in this document. In most cases you want to localize these variables before changing them, since if you don't, the change may affect other modules which rely on the default values of the special variables that you have changed. This is one of the correct ways to read the whole file at once: open my $fh, "foo" or die $!; local $/; # enable localized slurp mode my $content = <$fh>; close $fh; But the following code is quite bad: open my $fh, "foo" or die $!; undef $/; # enable slurp mode my $content = <$fh>; close $fh; since some other module, may want to read data from some file in the default "line mode", so if the code we have just presented has been executed, the global value of $/ is now changed for any other code run- ning inside the same Perl interpreter. Usually when a variable is localized you want to make sure that this change affects the shortest scope possible. So unless you are already inside some short "{}" block, you should create one yourself. For exam- ple: my $content = ''; open my $fh, "foo" or die $!; { local $/; $content = <$fh>; } close $fh; [/snip] With this said, can you reproduce this problem with the following test code: [snip] #!/usr/bin/perl use warnings; use strict; use Data::Serializer; use Data::Dumper; my $d = Data::Serializer->new(); { local $/; my $ref = {a => 'b'}; my $serialized = $d->serialize($ref); #$d->store($ref,'store.txt'); open(OUT, '>', 'store.txt') || die "Couldn't write to store.txt: $!\n"; print OUT "$serialized\n\n\n"; close(OUT); } #File method my $thaw = $d->retrieve('store.txt'); print Dumper $thaw; #Filehandle method open(IN, '<', 'store.txt'); my $fh_thaw = $d->retrieve(\*IN); close(IN); print Dumper $fh_thaw; [/snip] As you can see from the above, that is storing a serialized value followed with three newlines, with a localized $/ undefined. As long as $/ remains correctly defined on the reading side these functions should operate correctly. My main hesitation with altering this behavior is that I like the functionality of $/ as it varies per OS, and by relying on it being correctly set it keeps Data::Serializer from having to understand or care about what that value happens to be. That said, I am open to being convinced otherwise and making Data::Serializer play nicer with those who mess with their $/ in the global namespace. -- Neil On Dec 12, 2006, at 8:50 AM, Jamie Lentin via RT wrote: Show quoted text
> > Tue Dec 12 10:50:49 2006: Request 23901 was acted upon. > Transaction: Ticket created by lentinj > Queue: Data-Serializer > Subject: Data::Serializer::Retrieve doesn't slurp files > Broken in: 0.32, 0.36 > Severity: Normal > Owner: Nobody > Requestors: jamie.lentin@bbc.co.uk > Status: new > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=23901 > > > > If you try to use retrieve to read a file that contains a newline, the > deserialization won't work. When retrieve() reads a file into $input, > it will stop at any \n in the file since $/ is still defined. > > A "local $/" at the beginning of the function should sort it. Or > alternatively using File::Slurp or something. > > Cheers for all your work!