How to print Package Variables - perl

How to Print all package variables in Perl.
I have 2 packages in same script, I want to get all the variables used in packageA in packageB

What problem are you trying to solve?
But, there are so many other design issues here.
If there's some central source of truth for values in your program, that package can provide an interface to request a value. This is what I tend to do.
They are package variables, so package B can just use the variables from package A: $A::some_var.
package A could export all of its variables to any other package that wants to use them. Several Perl modules, such as Socket and Fcntl, do this.
If package B is really just a specialization of package A, inheritance might be the answer. You still need an interface though.

Related

use symbols from module without package (require)

I already asked a similar question, but it had more to do with using barewords for functions. Basically, I am refactoring some of my code as I have begun learning about "package" and OOP in perl. Since none of my modules used "package" I could just "require" them into my code, and I was able to use their variables and functions without any trouble. But now I have created a module that I will be using as a class for object manipulation, and I want to continue being able to use my functions in other modules in the same way. No amount of reading docs and tutorials has quite answered my question, so please, if someone can offer an explanation of how it works, and why, that would go a really long way, more than a "this is how you do it"-type answer.
Maybe this can illustrate the problem:
myfile.cgi:
require 'common.pm'
&func_c('hi');
print $done;
common.pm:
$done = "bye";
sub func_c {print #_;}
will print "hi" then "bye", as expected.
myfile_obj.cgi:
use common_obj;
&func_obj('hi');
&finish;
common_obj.pm:
package common_obj;
require 'common.pm';
sub func_obj {&func_c(#_);}
sub finish {print $done;}
gives "Undefined subroutine func_c ..."
I know (a bit) about namespaces and so on, but I don't know how to achieve the result I want (to get func_obj to be able to call func_c from common.pm) without having to modify common.pm (which might break a bunch of other modules and scripts that depend on it working the way it is). I know about use being called as a "require" in BEGIN along with its import().. but again, that would require modifying common.pm. Is what I want to accomplish even possible?
You'll want to export the symbols from package common_obj (which isn't a class package as it stands).
You'll want to get acquainted with the Exporter module. There's an introduction in Modern Perl too (freely available book, but consider buying it too).
It's fairly simple to do - if you list functions in #EXPORT_OK then they can be made available to someone who uses your package. You can also group functions together into named groups via EXPORT_TAGS.
Start by just exporting a couple of functions, list those in your use statement and get the basics. It's easy enough then.
If your module was really object-oriented then you'd access the methods through an object reference $my_obj->some_method(123) so exporting isn't necessary. It's even possible for one package to offer both procedural/functional and object-oriented interfaces.
Your idea of wrapping old "unsafe" modules with something neater seems a sensible way to proceed by the way. Get things under control without breaking existing working code.
Edit : explanation.
If you require a piece of unqualified code then its definitions will end up in the requiring package (common_obj) but if you restrict code inside a package definition and then use it you need to explicitly export definitions.
You can use common_obj::func_obj and common_obj::finish. You just need to add their namespaces and it will work. You don't need the '&' in this case.
When you used the package statement (in common_obj.pm) you changed the namespace for the ensuing functions. When you didn't (in common.pm) you included the functions in the same namespace (main or common_obj). I don't believe this has anything to do with use/require.
You should use Exporter. Change common_obj to add:
use base Exporter;
#EXPORT_OK = qw/func_obj finish/;
Then change myfile_obj:
use common_obj qw/func_obj finish/;
I am assuming you are just trying to add a new interface into an old "just works" module. I am sure this is fraught with problems but if it can be done this is one way to do it.
It's very good that you're making the move to use packages as that will help you a lot in the future. To get there, i suggest that you start refactoring your old code as well. I can understand not wanting to have to touch any of the old cgi files, and agree with that choice for now. But you will need to edit some of your included modules to get where you want to be.
Using your example as a baseline the goal is to leave myfile.cgi and all files like it as they are without changes, but everything else is fair game.
Step 1 - Create a new package to contain the functions and variables in common.pm
common.pm needs to be a package, but you can't make it so without effecting your old code. The workaround for this is to create a completely new package to contain all the functions and variables in the old file. This is also a good opportunity to create a better naming convention for all of your current and to be created packages. I'm going to assume that maybe you don't have it named as common.pm, but regardless, you should pick a directory and name that bits your project. I'm going to randomly choose the name MyProject::Core for the functions and variables previously held in common.pm
package MyProject::Core;
#EXPORT = qw();
#EXPORT_OK = qw($done func_c);
%EXPORT_TAGS = (all => [#EXPORT, #EXPORT_OK]);
use strict;
use warnings;
our $done = "bye";
sub func_c {
print #_, "\n";
}
1;
__END__
This new package should be placed in MyProject/Core.pm. You will need to include all variables and functions that you want exported in the EXPORT_OK list. Also, as a small note, I've added return characters to all of the print statements in your example just to make testing easier.
Secondly, edit your common.pm file to contain just the following:
use MyProject::Core qw(:all);
1;
__END__
Your myfile.cgi should work the same as it always does now. Confirm this before proceeding.
Next you can start creating your new packages that will rely on the functions and variables that used to be in the old common.pm. Your example common_obj.pm could be recoded to the following:
package common_obj;
use MyProject::Core qw($done func_c);
use base Exporter;
#EXPORT_OK = qw(func_obj finish);
use strict;
use warnings;
sub func_obj {func_c(#_);}
sub finish {print "$done\n";}
1;
__END__
Finally, myfile_obj.cgi is then recoded as the so:
use common_obj qw(func_obj finish);
use strict;
use warnings;
func_obj('hi');
finish();
1;
__END__
Now, I could've used #EXPORT instead of #EXPORT_OK to automatically export all the available functions and variables, but it's much better practice to only selectively import those functions you actually need. This method also makes your code more self-documenting, so someone looking at any file, can search to see where a particular function came from.
Hopefully, this helps you get on your way to better coding practices. It can take a long time to refactor old code, but it's definitely a worthwhile practice to constantly be updating ones skills and tools.

How to refer to parent package in relative package import?

I'd like to import package com.example.abc from com.example.iop in similar manner to bash expression ../abc.
Is this possible in Scala? I've read couple of articles but they say nothing about my case.
Update: I've discovered code suitable for simple uses (I've seen it in some project while ago):
package com.example
package com.example.abc
import iop
Your updated package structure has a hint of the solution, but isn't quite right. You can live in multiple packages, including a broad parent package defined by the first package statement – subsequent statements refine the tree.
package com.foo // we're in: com.foo
package bar // we're also in: com.foo.bar
package wibble // we're also in: com.foo.bar.wibble
import frobble._ // this could be com.foo.frobble or com.foo.bar.frobble or com.foo.bar.wibble.frobble
Obviously, things can get confusing if you have multiple packages with the same name, but the compiler asks you politely to sort that out.
That is simply not possible -- same as in Java.

Perl: Dynamic module loading, object inheritance and "common helper files"

In a nutshell I try to model a network topology using objects for every instance in the network. Additionally I got a top-level manager class responsible for, well, managing these objects and performing integrity checks. The filestructure looks like this (I left out most of the object-files as they are all structured pretty equal):
Manager.pm
Constants.pm
Classes/
+- Machine.pm
+- Node.pm
+- Object.pm
+- Switch.pm
Coming from quite a few years in OOP, I'm a fan of code reuse etc. so I set up inheritance between thos objects, the inheritance tree (in this example) looks like this:
Switch -+-> Node -+-> Object
Machine -+
All those objects are structured like this:
package Switch;
use parent qw(Node);
sub buildFromXML {
...
}
sub new {
...
}
# additonal methods
Now the interesting part:
Question 1
How can I ensure correct loading of all those objects without typing out the names statically?
The underlying problem is: If I just require "$_" foreach glob("./Classes/*"); I get many "Subroutine new redefined at" errors. I also played around with use parent qw(-norequire Object), Module::Find and some other #INC modifications in various combinations, to make it short: It didn't work. Currently I'm statically importing all used classes, they auto-import their parent classes.
So basically what I'm asking: What is the (perl-)correct way of doing this?
And advanced: It would be very helpful to be able to create a more complex folder structure (as there will be quite a few objects) and still have inheritance + "autoloading"
Question 2 - SOLVED
How can I "share my imports"? I use several libraries (my own, containing some helper functions, LibXML, Scalar::Util, etc.) and I want to share them amongst my objects. (The reasoning behind that is, I may need to add another common library to all objects and chances are high that there will be well above 100 objects - no fun editing all of them manually and doing that with a regex / script would theoretically work but that doesn't seem like the cleanest solution available)
What I tried:
import everything in Manager.pm -> Works inside the Manager package - gives me errors like "undefined subroutine &Switch::trace called"
Create a include.pl file and do/require/use it inside every object - gives me the same errors.
Some more stuff I sadly don't remember
include.pl basically would look like that:
use lib_perl;
use Scalar::Util qw(blessed);
use XML::LibXML;
use Data::Dumper;
use Error::TryCatch;
...
Again I ask: What's the correct way to do it? Am I using the right approach and just failing at the execution or should I change my structure completely?
It doesn't matter that much why my current code doesn't work that well, providing a correct, clean approach for those problems would be enough by far :)
EDIT: Totally forgot perl version -_- Sidenote: I can't upgrade perl, as I need libraries that are stuck with 5.8 :/
C:\> perl -version
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 50 registered patches, see perl -V for more detail)
Copyright 1987-2006, Larry Wall
Binary build 820 [274739] provided by ActiveState http://www.ActiveState.com
Built Jan 23 2007 15:57:46
This is just a partial answer to question 2, sharing imports.
Loading a module (via use) does two things:
Compiling the module and installing the contents in the namespace hierarchy (which is shared). See perldoc -f require.
Calling the import sub on each loaded module. This loads some subs or constants etc. into the namespace of the caller. This is a process that the Exporter class largely hides from view. This part is important to use subs etc. without their full name, e.g. max instead of List::Util::max. See perldoc -f use.
Lets view following three modules: A, B and User.
{
package A;
use List::Util qw(max);
# can use List::Util::max
# can use max
}
{
package User;
# can use List::Util::max -> it is already loaded
# cannot use max, this name is not defined in this namespace
}
Package B defines a sub load that loads a predefined list of modules and subs into the callers namespace:
{
package B;
sub load {
my $package = (caller())[0]; # caller is a built-in, fetches package name
eval qq{package $package;} . <<'FINIS' ;
use List::Util qw(max);
# add further modules here to load
# you can place arbitrarily complex code in this eval string
# to execute it in all modules that call this sub.
# (e.g. testing and registering)
# However, this is orthogonal to OOP.
FINIS
if ($#) {
# Do error handling
}
}
}
Inside the eval'd string, we temporarily switch into the callers package and then load the specified module. This means that the User package code now looks like this:
{
package User;
B::load();
# can use List::Util::max
# can use max
}
However, you have to make sure the load sub is already loaded itself. use B if in doubt. It might be best to execute B::load() in the BEGIN phase, before the rest of the module is compiled:
{
package User;
BEGIN {use B; B::load()}
# ...
}
is equivalent to
{
package User;
use B;
use List::Util qw(max);
# ...
}
TIMTOWTDI. Although I find evaling code quite messy and dangerous, it is the way I'd pursue in this scenario (rather than doing files, which is similar but has different side effects). Manually messing with typeglobs in the package namespace is hell in comparision, and copy-pasting a list of module names is like going back to the days when there wasn't even C's preprocessor.
Edit: Import::Into
… is a CPAN module providing this functionality via an interesting method interface. Using this module, we would redefine our B package the following way:
{
package B;
use List::Util; # you have to 'use' or 'require' this first, before using 'load'.
use Import::Into; # has to be installed from CPAN first
sub load {
my $package = caller;
List::Util->import::into($package, qw(max));
# should work too: strict->import::into($package);
# ...
}
}
This module hides all the dirty work (evaling) from view and does method call resolution gymnastics to allow importing pragmas into other namespaces.
Addendum to Import::Into Solution
I found a scenario that seems to require eval() from within the Import::Into solution. In this scenario, mod User is effectively among the uses from package B. This may be a common scenario for people using Import::Into.
Specifics:
I created module uses_exporter with separate subs for importing
different groups of modules, e.g. load_generic() and
load_list_utils().
The uses in load_list_utils() are to public mods like
List::MoreUtils, AND to a module of my own, list_utils_again. That
local module also calls load_list_utils(). The call fails if
load_list_utils() uses list_utils_again.
My solution was to put the use to list_utils_again into an eval which
does not excecute when $target eq 'list_utils_again'
The correct idiomatic Perl way to do this is not to always load a bunch a modules whether used or not; it is to have every file use those modules it directly (not indirectly) needs.
If it turns out that every file uses the same set of modules, you might make things simpler by having a single dedicated module to use all those in that common set.

Using use without package - big mess?

I have been USEing .pm files willy-nilly in my programs without really getting into using packages unless really needed. In essence, I would just have common routines in a .pm and they would become part of main when use'd (the .pm would have no package or Exporter or the like... just a bunch of routines).
However, I came across a situation the other day which I think I know what happened and why, but I was hoping to get some coaching from the experts here on best practices and how to resolve this. In essence, should packages be used always? Should I "do" files when I just want common routines absorbed into main (or the parent module/package)? Is Exporter really the way to handle all of this?
Here's example code of what I came across (I won't post the original code as it's thousands of lines... this is just the essence of the problem).
Pgm1.pl:
use PM1;
use PM2;
print "main\n";
&pm2sub1;
&pm1sub1;
PM1.pm:
package PM1;
require Exporter;
#ISA=qw(Exporter);
#EXPORT=qw(pm1sub1);
use Data::Dump 'dump';
use PM2;
&pm2sub1;
sub pm1sub1 {
print "pm1sub1 from caller ",dump(caller()),"\n";
&pm2sub1;
}
1;
PM2.pm:
use Data::Dump 'dump';
sub pm2sub1 {
print "pm2sub1 from caller ",dump(caller()),"\n";
}
1;
In essence, I'd been use'ing PM2.pm for some time with its &pm2sub1 subroutine. Then I wrote PM1.pm at some point and it needed PM2.pm's routines as well. However, in doing it like this, PM2.pm's modules got absorbed into PM2.pm's package and then Pgm1.pl couldn't do the same since PM2.pm had already been use'd.
This code will produce
Undefined subroutine &main::pm2sub1 called at E:\Scripts\PackageFun\Pgm1.pl line 4.
pm2sub1 from caller ("PM1", "PM1.pm", 7)
main
However, when I swap the use statements like so in Pgm1.pl
use PM2;
use PM1;
print "main\n";
&pm2sub1;
&pm1sub1;
... perl will allow PM2.pm's modules into main, but then not into PM1.pm's package:
Undefined subroutine &PM1::pm2sub1 called at PM1.pm line 7.
Compilation failed in require at E:\Scripts\PackageFun\Pgm1.pl line 2.
BEGIN failed--compilation aborted at E:\Scripts\PackageFun\Pgm1.pl line 2.
So, I think I can fix this by getting religious about packages and Exporter in all my modules. Trouble is, PM2.pm is already used in a great number of other programs, so it would be a ton of regression testing to make sure I didn't break anything.
Ideas?
See my answer to What is the difference between library files and modules?.
Only use require (and thus use) for modules (files with package, usually .pm). For "libraries" (files without package, usually .pl), use do.
Better yet, only use modules!
use will not load same file more than once. It will, however, call target package's import sub every time. You should format your PM2 as proper package, so use can find its import and export function to requestor's namespace from there.
(Or you could sneak your import function into proper package by fully qualifying its name, but don't do that.)
You're just asking for trouble arranging your code like this. Give each module a package name (namespace), then fully qualify calls to its functions, e.g. PM2::sub1() to call sub1 in package PM2. You are already naming the functions with the package name on them (pm2sub1); it is two extra characters (::) to do it the right way and then you don't need to bother with Exporter either.

Perl: how to share the import of a large list of modules between many independent scripts?

I have many standalone scripts. The only thing they share, is that they use() a large set of CPAN modules (that each export several functions). I would like to centralize this list of modules. I found several methods. Which one is the best?
I could create SharedModules.pm that imports everything and then manually exports everything to main:: using Exporter.
I could create SharedModules.pm that starts with "package main;" so it will import directly into main::. It seems to work. Is it bad practice and why?
I could require() a sharedmodules.pl that seems to import everything into main:: as well. I don't like this method as require() doesn't work that well under mod_perl.
Number two looks best to me, however I wonder why for example Modern::Perl doesn't work that way.
Edit: I figured this question has been asked before.
Maybe more flexible than putting everything into main namespace would be to import into caller's namespace. Something like this:
package SharedModules;
sub import {
my $pkg = (caller())[0];
eval <<"EOD";
package $pkg;
use List::Util;
use List::MoreUtils;
EOD
die $# if $#;
}
1;
The problem with all three of your proposed solutions is that the module may be used from another module, in which case the symbols should be exported into the useing module's package, not into main.
bvr's solution of using caller to import things directly into that package is a major step in the right direction, but prevents the 'real' package from using use ShareableModules qw( foo bar baz); to selectively import only what it actually needs.
Unfortunately, preserving the ability to import selectively will require you to import all relevant symbols from the underlying modules and then re-export them from ShareableModules. You can't just delegate the import to each underlying module's import method (as Modern::Perl does) because import dies if it's asked for a symbol that isn't exported by that module. If that's not an issue, though, then Modern::Perl's way of doing it is probably the cleanest and simplest option.
Using require is the most natural way to do this. Under mod_perl you may need to modify #INC during server startup.
Maybe you want Toolkit.
File import.pl:
require blah; blah->import;
require blubb; blubb->import;
Skripts:
#!/usr/bin/perl
do 'import.pl'
...
Patrick