Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: using a variable with require

by GrandFather (Saint)
on Jun 22, 2022 at 04:23 UTC ( [id://11144936]=note: print w/replies, xml ) Need Help??


in reply to using a variable with require

A nasty solution to the invocation problem is to use eval. If SomeModule comes from the outside world this is a really bad solution!

use strict; use warnings; my $modName = 'Getopt::Long'; my $fixedMod = $modName; $fixedMod =~ s!::!/!g; $fixedMod .= '.pm'; require $fixedMod; my $length = 24; eval "${modName}::GetOptions('length:i' => \\\$length)";

However, there may be a much better solution to your big picture issue. What are you trying to do that seems to need a require?

Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond

Replies are listed 'Best First'.
Re^2: using a variable with require
by geoffleach (Scribe) on Jun 22, 2022 at 13:02 UTC
    Thanks. While I digest this suggestion, here's the big picture as requested. I download podcasts from a number of sources. Each feed has its own peculiarities, requiring feed-specific coding, which I wish to isolate as modules. On the other hand, local processing is not feed-specific.
    % download_processor feed1 % download_processor feed2 % ....
    and there are modules feed1.pm, feed2.pm, and so on. What I would like to accomplish is when a new feed comes along, I just write a module for the new feed and don't have to modify the download_processor.

      You can do that in a very light weight way by creating a package for each feed type. They can be in a single file or multiple files or even the main file. If not in the main file you can use or require as suits your purpose then create an instance of the appropriate type. Consider:

      use strict; use warnings; package FetchOne; sub new { my ($class, %params) = @_; return bless\%params, $class; } sub type { return 'Fetch type One'; } package FetchTwo; sub new { my ($class, %params) = @_; return bless\%params, $class; } sub type { return 'Fetch type Two'; } package main; my $type = 'Two'; my $obj = "Fetch$type"->new(); print $obj->type();

      Prints:

      Fetch type Two
      Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
      The usual pattern for this is to put each implementation into a package hierarchy of objects, then know the package name you want to load, then:

      use Module::Load; ... load $package; my $obj= $package->new( %options ); $obj->do_something;

      No need for awkward cross-package function-calls.

      Maybe GrandFather wanted to recommend a plugin-supporting module (e.g. Module::Pluggable)?

      geoffleach:

      Your question already seems to be solved, but I thought I'd post a note with respect to your original problem and the use case you're describing here. The name of the file and the name of the package inside it isn't necessarily related. That's one of the difficulties that I expect Grandfather and others were thinking about.

      So one thing you can do is use the same package name for all of your podcast processors. Then you can do something like:

      $podcast_name = 'comedy_with_joe'; require "podcast_processors/${podcast_name}.pm"; PodcastProcessor::somesub();

      where each of your podcast processor modules would look like:

      # process podcasts for XYZ package PodcastProcessor; ... yadda ... sub somesub { ... }

      ...roboticus

      When your only tool is a hammer, all problems look like your thumb.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11144936]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-03-28 11:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found