http://qs321.pair.com?node_id=192644

rattusillegitimus has asked for the wisdom of the Perl Monks concerning the following question:

I've been making a lot of progress in the XML Resume modules I first posted about here, but I've run into a problem with my default XSL stylesheets. Each resume format (Text, HTML, etc), has a default stylesheet I've been using and would like to distribute with the module. I had the idea that rather than using an external file for each of them, I'd stuck them in the __DATA__ section of the module, and pull them in using the <DATA> filehandle. This gives me an output subroutine similar to the following in each of the Resume::Text, Resume::HTML, etc, modules:

sub output { my $self = shift; my ($dom, $xslfile, $stylesheet); if ($self->{'stylesheet'}) { $xslfile = $self->{'basedir'} . $self->{'stylesheet'}; $stylesheet = $self->{'xslt'}->parse_stylesheet_file($xslfile) +; } else { local $/ = undef; my $doc = $self->{'parser'}->parse_string(<DATA>); $stylesheet = $self->{'xslt'}->parse_stylesheet($doc); } $dom = $stylesheet->transform($self->{'dom'}); return $dom->toString(); }

Because each of the modules needs to apply an XSL stylesheet to the XML document containing the resume, I figured I should abstract that part of the output sub into a apply_stylesheet sub in the parent Resume object like so:

sub apply_stylesheet { my $self = shift; my ($dom, $xslfile, $stylesheet); if ($self->{'stylesheet'}) { $xslfile = $self->{'basedir'} . $self->{'stylesheet'}; $stylesheet = $self->{'xslt'}->parse_stylesheet_file($xslfile) +; } else { local $/ = undef; my $doc = $self->{'parser'}->parse_string(<DATA>); $stylesheet = $self->{'xslt'}->parse_stylesheet($doc); } $dom = $stylesheet->transform($self->{'dom'}); return $dom; }

However, as would be obvious to people with more OO experience than I have, when the output sub in a Resume::Text object calls apply_stylesheet (which is defined in the parent Resume package, rather in the child Resume::Text package), the the sub tries to read the data in the __DATA__ section of Resume.pm, not the one in Resume/Text.pm.

If this is a totally wrong-headed way of approaching this issue, please let me know. ;) If not, I'm sure there's a relatively simple solution that I haven't managed to get into my head yet. I'm still fairly new to OO in Perl, and I don't quite grok all it's subtleties yet.

Thanks for any help you can give me,
-rattus
__________
He seemed like such a nice guy to his neighbors / Kept to himself and never bothered them with favors
- Jefferson Airplane, "Assassin"

Replies are listed 'Best First'.
Re: OO and <DATA>
by dws (Chancellor) on Aug 25, 2002 at 07:04 UTC
    However, as would be obvious to people with more OO experience than I have, when the output sub in a Resume::Text object calls apply_stylesheet (which is defined in the parent Resume package, rather in the child Resume::Text package), the the sub tries to read the data in the __DATA__ section of Resume.pm, not the one in Resume/Text.pm.

    You can deal with this problem by further isolating your use of the __DATA__ section behind a method that does a one-time, lazy setup from <DATA>. This turns   my $doc = $self->{'parser'}->parse_string(<DATA>); into

    my $stylesheet = $self->get_stylesheet(); my $doc = $self->{'parser'}->parse_string($stylesheet);

    This also frees you to override get_stylesheet() in subclasses. How and where get_stylesheet() gets the stylesheet is an implementation detail. A subclass needn't use the __DATA__ section.

      dws is correct, but I don't know if the __DATA__ concern is clear enough for newer users. __DATA__ is only read ONCE during the execution of a script, any secondary calls to it will result in an empty string.

      I have found it helpful to use something like Text::Template to store information that will be read in multiple times and if setup correctly will allow for edits while the process is running. I like Text::Template for its simplicity, but there are dozens of templating options that might help here.

        Does seek data,0; not work?
Re: OO and <DATA>
by Zaxo (Archbishop) on Aug 25, 2002 at 05:56 UTC

    I do think it's wrong. Your module is intended to produce an xml document. The advantage of that is independence of representation. The associated xsl transformations should depend on the xml doctype, but not be a part of the document itself.

    By modularizing an xml doctype in perl you have made it highly dynamic. No need to throw that away.

    After Compline,
    Zaxo

      Thanks, Zaxo. You hit me right between the eyes with a reminder of the secondary purpose of my Resume modules. The first, of course, was to be able to generate my own and my wife's resumes easily in a number of formats, and I was spending too much time worrying about making that easier and not enough thinking forward to keeping everything dynamic and configurable by anyone who might install and use the modules. I'm going to back the default stylesheet issue back out into the sample and test scripts instead.

      That being said, I also want to thank dws, trs80, and BUU for showing me how I would use the __DATA__ section in this way and the potential pitfalls thereof. I'm sure that knowledge will come in handy ;)

      -rattus
      __________
      He seemed like such a nice guy to his neighbors / Kept to himself and never bothered them with favors
      - Jefferson Airplane, "Assassin"