Can I change lines of code in a loaded module in Perl?

When I use a module FLV::Infoto extract metadata from or merge several FLV files, I often get a "Tag size too small" error, and then the module simply refuses to work. Someone posted a bug report here three years ago, but there seems to have been no fix.

Well, I recently discovered that I would just comment on the following lines of code in Tag.pm, one of the dependency modules FLV::Info, for example:

=pod
if ($datasize < 11)
   {
      die "Tag size is too small ($datasize) at byte " . $file->get_pos(-10);
   }
=cut

FLV::Info then easily do the work as expected.

I'm not sure this is a very stupid question, but I'm curious:

Is there an easy way to change a couple lines of code in a loaded module without changing the source .pm file?

Any ideas, suggestions or comments? Thanks, as always :)

UPDATE

@Shwern. :) @DVK " " @brian .

FLV , " ", , .

"eval it back"

use FLV::Info;

use Data::Dump::Streamer;
my $original = FLV::Tag->can("parse");
my $code = Dump($original)->Out;
#$code =~ s{\Qif ($datasize < 11)\E}{if (0)}; #This somehow won't work
$code =~ s{die "Tag}{warn "Tag}; #Let it warn but not die

no warnings 'redefine';
*FLV::Tag::parse = eval $code;

my $reader = FLV::Info->new();
$reader->parse('sample.flv');
my %info = $reader->get_info();
print "$info{video_count} video frames\n";
print $reader->report();

"over die die to not die"

BEGIN {
    *CORE::GLOBAL::die = sub { return CORE::die(@_) };
}
use FLV::Info;

{
    local *CORE::GLOBAL::die = sub {
         return if $_[0] =~ /^Tag size is too small/;
         return CORE::die(@_);
};

my $reader = FLV::Info->new();
$reader->parse('sample.flv');
my %info = $reader->get_info();
print "$info{video_count} video frames\n";
print $reader->report();
}

"" , .

FLV:: Tag:: parse , Tag.pm :

use FLV::Info;
no warnings 'redefine';
*FLV::Tag::parse = sub {
    ...
    ...
=pod
   if ($datasize < 11)
   {
      die "Tag size is too small ($datasize) at byte " . $file->get_pos(-10);
   }
=cut
   ...
   ...
};

my $reader = FLV::Info->new();
$reader->parse('sample.flv');
my %info = $reader->get_info();
print "$info{video_count} video frames\n";
print $reader->report();

:

Unknown tag type 18 at byte 13 (0xd)

, ​​ - , " " " ".

!

, "eval it back" "override die to not die" :

1992 video frames
File name                sample.flv
File size                5767831 bytes
Duration                 about 79.6 seconds
Video                    1992 frames
  codec                  AVC
  type                   interframe/keyframe
Audio                    1712 packets
  format                 AAC
  rate                   44100 Hz
  size                   16 bit
  type                   stereo
Meta                     1 event
  audiocodecid           10
  audiosamplerate        22050
  audiosamplesize        16
  audiosize              342817
  creationdate           unknown
  datasize               805
  duration               79.6
  filesize               5767869
  framerate              25
  height                 300
  keyframes              {
    >>>                    'filepositions' => [
    >>>                                         '780',
    >>>                                         '865',
    >>>                                         '1324122',
    >>>                                         '2348913',
    >>>                                         '2978630',
    >>>                                         '3479001',
    >>>                                         '3973756',
    >>>                                         '4476281',
    >>>                                         '4997226',
    >>>                                         '5391890'
    >>>                                       ],
    >>>                    'times' => [
    >>>                                 '0',
    >>>                                 '0',
    >>>                                 '9.6',
    >>>                                 '19.2',
    >>>                                 '28.8',
    >>>                                 '38.4',
    >>>                                 '46.32',
    >>>                                 '55.92',
    >>>                                 '64.88',
    >>>                                 '73.88'
    >>>                               ]
    >>>                  }
  lastkeyframetimestamp  73.88
  lasttimestamp          79.6
  metadatacreator        Manitu Group FLV MetaData Injector 2
  metadatadate           1281964633858
  stereo                 1
  videocodecid           7
  videosize              5424234
  width                  400

, "" , . @Schwern :)

( FLV:: Util), FLV:: Tag:: parse.

Readonly::Hash our %TAG_CLASSES => (
   8  => 'FLV::AudioTag',
   9  => 'FLV::VideoTag',
   18 => 'FLV::MetaTag',
);
+5
2

? . , . .

, .pm , - , .

, .

use FLV::Tag;

no warnings 'redefine';
*FLV::Tag::parse = sub {
    ...copy of FLV::Tag::parse with your edits...
};

die, , .

BEGIN {
    # In order to override die() later, you must override it at compile time.
    *CORE::GLOBAL::die = sub { return CORE::die(@_) };
}

{
    local *CORE::GLOBAL::die = sub {
        return if $_[0] =~ /^Tag size too small/;
        return CORE::die(@_);
    }

    ...do your thing...
}

Perl, .

use Data::Dump::Streamer;
my $original = FLV::Tag->can("parse");
my $code = Dump($original)->Out;
$code =~ s{\Qif ($datasize < 11)\E}{if( 0 )};

no warnings 'redefine';
*FLV::Tag::parse = eval $code;

, - .

. , .

+18

, , , ""...

( )... ... FLV::Info ( FLV::Tag).

, ( ?), , "", , . , .

+3

All Articles