1

I have an object that uses freezes data as such:

sub frozen_data {
    my $self = shift;

    $Data::Dumper::Indent = 0;
    $Data::Dumper::Terse  = 1;
    return Data::Dumper->Dump( [ $self->{_DATA}, ] );
}

and a corresponding thaw:

sub thaw_data {
    my ($self) = @_;

    $self->{_DATA} = eval $self->{DATA};
}

this seems to work well, are there any issues with it? I also tried running this by perlcritic, and I get this:

Expression form of "eval" at line 69, column 22.  See page 161 of PBP.  (Severity: 5)

What's the better way to write this?

Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
Timmy
  • 12,468
  • 20
  • 77
  • 107
  • The eval only retrieves data that the class itself generates, except for the round-trip from-to the database. – Timmy Jan 07 '10 at 22:36

5 Answers5

8

You get around it by telling Perl Critic to STFU :)

 $self->{_DATA} = eval $self->{DATA}; ## no critic

Sometimes you need to do the thing that is only generally a bad practice.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
5

There's no way around it if you're thawing output from Data::Dumper. An alternative is Storable.

If you're accepting untrusted inputs and handing them unchecked to eval, you should immediately redesign this mechanism because it leaves the front door wide open. For marshalling internal data, I wouldn't sweat the warning.

Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
5

As long as you know the only source of that data is the frozen data you yourself have created using Dumper, you're fine.

The alternative is to use something other than Dumper, such as Storable.

Dan
  • 10,990
  • 7
  • 51
  • 80
5

Decide what you want to allow or forbid and set up a Safe compartment and use its reval method.

ysth
  • 96,171
  • 6
  • 121
  • 214
  • Thanks, will definitely read into Safe. In theory the data, other the save/retrieve from the database, is internal, but prefer to be more defensive! – Timmy Jan 07 '10 at 22:38
0

For anyone looking at this and wondering whether to roll their own serialization, there might be some benefit gained by looking at this blog post that compares a list of several existing serializers and gives some advantages and disadvantages of each:

http://blogs.perl.org/users/steven_haryanto/2010/09/comparison-of-perl-serialization-modules.html

He mentions Data::Dumper, Storable, YAML::XS, Data::Dump, XML::Dumper, JSON::XS, JSYNC, and FreezeThaw. He concludes that there are features missing from all of them:

In conclusion, choice is good but I have not found my perfect general serialization module yet. My two favorites are Storable and YAML::XS. If JSYNC [was] faster and supported Regexp, or if YAML::XS or YAML::Syck [could] output inline/compact YAML, that would be as near to perfect as I would like it.

Also see the points people made in the comments. It's just good to get the perspective of people who've run into issues before, etc.

If you are rolling your own serialization, you might want to look at the pros and cons mentioned there (speed, ability to handle things like regular expressions and circular references, etc). This can possibly head off problems for you that you haven't realized you were likely to run into.

Also, when you are using Dumper for serialization, it's good to understand all the options Data::Dumper gives you for output.

Is it going into a database where, some time in the future, someone is going to want to do a SQL query with a LIKE pattern? If so, you'll be happy you used Sortkeys because then you can do LIKE '%akey=front%ckey=front_of_c%' and you only have one ordering to worry about instead of n factorial.

As an example, here's what a friend of mine uses for serialization with Dumper:

my $deflated = Data::Dumper->new([$data])->Purity(1)->Terse(1)->Deepcopy(1)->Sortkeys(1)->Indent(1)->Dump;

I would recommend reading the docs of Dumper so you can understand what modifications those options make.

msouth
  • 832
  • 11
  • 21