Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Thursday February 14, 2008
06:51 AM

Relocatable Code in Bermuda

[ #35652 ]

The problem: Bermuda needs to be relocatable. This means that a lot of the auto-generated code needs to not require that Bermuda be installed. My Bermuda::Writer package needs to supply a base serialization class, but I need to test this class. To do that, I had Bermuda::Serialize::Base both in its own file, but also embedded in my Bermuda writer as a string.

That duplication is bad, but someone needs control over their serialization base class name and it shouldn't force them to use 'Bermuda', so here's what I did:

sub _base_class_code {
    my ( $class, $package ) = @_;

    my $writer = $INC{'Bermuda/Writer.pm'};
    my @path   = splitdir($writer);
    pop @path;    # discard Writer.pm
    my $base = catfile( @path, 'Serialize', 'Base.pm' );

    open my $fh, '<', $base or die "Cannot open ($base) for reading: $!";
    my $base_class_code = do { local $/; <$fh> };
    close $fh or die "Cannot close ($base): $!";
    $base_class_code =~ s/Bermuda::Serialize::Base/$package/gs;
    return $base_class_code;
}

This makes me feel really icky, but I've removed some duplication and now this code can be relocated.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Are you sure you want splitdir/catfile and not splitpath/catpath?

    • To be honest, I use those so seldom, I never really paid attention to the difference.

      Making both of those changes results in a lot of uninit value warnings from catpath, even though the tests pass :/

      sub catpath {
          my ($self,$volume,$directory,$file) = @_;

          # this gives me uninit warnings
          if ( $directory ne ''                &&
               $file ne ''             

      • Huh, what are you passing to it?

        • Er, um, really wish I had read the documentation rather than doing a quick %s/one/fortheother/. *blush*.

          • Heh. That’s what I meant by “Unix blinders” – and not pejoratively, as I used to wear them for the longest time myself. Unix is so nicely simple: no volumes, no distinct namespaces for file and directory names, just one uniform hierarchy… after a while one forgets the bizarre things that exist elsewhere.

    • I think it's actually spelled:

      use File::Basename;
      dirname($file);
  • How about a method that returns the serialiser code as a string (with selectable package name), which can then be evaled by the test file for testing?

    • I don't want to embed a string of code. I'm doing a huge amount of that already to do code generation and it makes a lot of my code hard to follow, despite aggressive refactoring. If I keep these packages in real packages, I get the benefits of my t/00-load.t test:

      #!perl

      use Test::More;
      use File::Spec::Functions 'splitdir';
      use File::Find;

      sub path_to_module {
          my $path = shift;
          $path =~ s/\.pm\z//;
          my @components = splitdir($path);
          shift @components;

      • Put it in a SelfLoader module and add a method to pull out the source via the package’s DATA handle? That way you avoid all the path diddling gymnastics and it automatically works as a standalone module.