Why can we access the subroutine even after specifying it in EXPORT_FAIL? - perl

Why, even after specifying subtract function in EXPORT_FAIL, am I able to access the function by defining it fully like mathematics::subtract? How can we completely make the function private?
package mathematics;
use Exporter;
#ISA = qw(Exporter);
#EXPORT = qw(add);
#EXPORT_FAIL = qw(subtract);
sub add() {
print("you can add numbers here"."\n");
}
sub subtract() {
print("you can subtract the numbers here"."\n");
}
1;

How can we completely make the function private???
You cannot. Perl doesn't have the concept of private or public.
You can however make it a lexical code reference and use that inside your code.
package Foo;
use strict;
use warnings;
my $_private = sub {
return "this is a secret";
}; # note the semicolon
sub bar {
return $_private->(); # call with reference syntax ->()
}
1;
As a lexical variable, it is now only accessible from within its scope. In this case, that scope is the file, not the package. So if you have multiple packages in one file, they can all see it. You cannot access it via a fully qualified name from outside the package.
By convention, things that should be handled as if they were private in Perl are named with a leading underscore _. That's how other developers know that something is not part of the public API of a module and that it's subject to change and should not be messed with. Of course that doesn't stop anybody from doing it, but generally there is no reason to stop them.
Also note that package names in Perl typically are written in camel case with the first letter being capitalised. Your package should be called Mathematics, and it should have use strict and use warnings.

From Perl 5.18, you can use lexical subroutines to achieve what you want. The documentation says this:
These subroutines are only visible within the block in which they are
declared, and only after that declaration:
# Include these two lines if your code is intended to run under Perl
# versions earlier than 5.26.
no warnings "experimental::lexical_subs";
use feature 'lexical_subs';
foo(); # calls the package/global subroutine
state sub foo {
foo(); # also calls the package subroutine
}
foo(); # calls "state" sub
my $ref = \&foo; # take a reference to "state" sub
my sub bar {
...
}
bar(); # calls "my" sub
p.s. Lexical subroutines are non-experimental from 5.26.

Related

How to create globally available functions in Perl?

Is it possible to create global functions available across all namespaces like perl built-in functions?
First of all, "function" is the name given to Perl's named list operators, named unary operators and named nullary operators. They are visible everywhere because they are operators, just like ,, && and +. Subs aren't operators.
Second of all, you ask how to create a global sub, but all subs are already global (visible from everywhere) in Perl! You simply need to quality the name of the sub with the package if it's not in the current package. For example, Foo::mysub() will call my_sub found in package Foo from anywhere.
But maybe you want to be able to say mysub() instead of Foo::mysub() from everywhere, and that's a very bad idea. It violates core principles of good programming. The number of types of problems it can cause are too numerous to list.
There is a middle ground. A better solution is to create a sub that can be imported into the namespaces you want. For example, say you had the module
package Foo;
use Exporter qw( import );
our #EXPORT_OK = qw( my_sub );
our %TAGS = ( ALL => \#EXPORT_OK );
sub my_sub { ... }
1;
Then, you can use
use Foo qw( my_sub );
to load the module (if it hasn't already been loaded) and create my_sub in the current package. This allows it to call the sub as my_sub() from the package into which it was imported.
There is nothing simple that would allow one to somehow "register" user's subs with the interpreter, or some such, so that you could run them as builtins in any part of the program.
One way to get the behavior you ask for is to directly write to symbol tables of loaded modules. This has to be done after the modules have been loaded, and after subs that you add to those modules have been defined. I use INIT block in the example below.
Note that this has a number of weaknesses and just in general the idea itself is suspect to me, akin to extending the interpreter. Altogether I'd much rather write a module with all such subs and use standard approaches for good program design to have that module loaded where it needs to go.
Having said that, here is a basic demo
use warnings;
use strict;
use feature 'say';
use Data::Dump qw(dd pp);
use TestMod qw(modsub);
sub t_main { say "In t_main(), from ", __PACKAGE__ }
modsub("Calling from main::");
INIT {
no strict 'refs';
foreach my $pkg (qw(TestMod)) {
*{ $pkg . '::' . 'sub_from_main' } = \&t_main;
}
dd \%TestMod::;
}
This copies the reference to t_main from the current package (main::) into the symbol table of $pkg, under the name of sub_from_main, which can then be used with that name in that package.
For simplicity the name of the module is hardcoded, but you can use %INC instead, and whatever other clues you have, to figure out what loaded modules' stashes to add to.
The benefactor (or the victim?) module TestMod.pm
package TestMod;
use warnings;
use strict;
use feature 'say';
use Exporter qw(import);
our #EXPORT_OK = qw(modsub);
sub modsub {
say "In module ", __PACKAGE__, ", args: #_";
say "Call a sub pushed into this namespace: ";
sub_from_main();
}
1;
The name of the added sub can be passed to modules as they're loaded, instead of being hardcoded, in which case you need to write their import sub instead of borrowing the Exporter's one.
There are also modules that allow one to add keywords, but that's no light alternative.
The answer seems to be no, but you can impliment most of the behaivior that you want by using the symbol table *main::main:: to define a subroutine in all the namespaces.
use strict;
use warnings;
use Data::Dump qw(dd);
my $xx = *main::main::;
package A;
sub test {
printf "A::%s\n", &the_global;
}
package B;
sub the_global
{
"This is B::the_global";
}
sub test {
printf "B::%s\n", &the_global;
}
package main;
my $global_sub = sub { "The Global thing" };
for my $NS (keys %$xx) {
if ($NS =~ /^[A-Z]::$/) {
my $x = $NS . 'the_global';
if (defined &$x) {
printf "Skipping &%s\n", $x;
} else {
printf "Adding &%s\n", $x;
no strict 'refs';
*$x = $global_sub;
}
}
}
A::test;
This will not work on packages that are not referenced at all before the for loop above is run. But this would only happen if a require, use or package was eval'd after the code started running.
This is also still a compiler issue! You either need to refer to the global function as the_global() or &the_global if you are (as you should be) using use strict.
Sorry for my late response and thank you all for yours detailed answers and explanations.
Well.. I understood the right answer is: IT'S NOT POSSIBLE!
I'm mantaining a Perl framework used by some customers, and that framework exports some specialized subs (logging, event handling, controllers for hardware devices, domain specific subs and so). That's why I tried to figure out how to prevent the developers from importing my subs in all their packages.

How to check whether Data::Dumper is installed? [duplicate]

I have Perl code which relies on Term::ReadKey to get the terminal width. My installation is missing this module, so I want to provide a default if the module isn't present rather than throw an exception.
How can I conditionally use an optional module, without knowing ahead of time whether it is available.
# but only if the module is installed and exists
use Term::ReadKey;
...
How can I accomplish this?
Here's a bare-bones solution that does not require another module:
my $rc = eval
{
require Term::ReadKey;
Term::ReadKey->import();
1;
};
if($rc)
{
# Term::ReadKey loaded and imported successfully
...
}
Note that all the answers below (I hope they're below this one! :-) that use eval { use SomeModule } are wrong because use statements are evaluated at compile time, regardless of where in the code they appear. So if SomeModule is not available, the script will die immediately upon compiling.
(A string eval of a use statement will also work (eval 'use SomeModule';), but there's no sense parsing and compiling new code at runtime when the require/import pair does the same thing, and is syntax-checked at compile time to boot.)
Finally, note that my use of eval { ... } and $# here is succinct for the purpose of this example. In real code, you should use something like Try::Tiny, or at least be aware of the issues it addresses.
Check out the CPAN module Module::Load::Conditional. It will do what you want.
The classic answer (dating back to Perl 4, at least, long before there was a 'use') was to 'require()' a module. This is executed as the script is run, rather than when compiled, and you can test for success or failure and react appropriately.
if (eval {require Term::ReadKey;1;} ne 1) {
# if module can't load
} else {
Term::ReadKey->import();
}
or
if (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}
Note: the 1; only executes if require Term::... loaded properly.
And if you require a specific version of the module:
my $GOT_READKEY;
BEGIN {
eval {
require Term::ReadKey;
Term::ReadKey->import();
$GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30;
};
}
# elsewhere in the code
if ($GOT_READKEY) {
# ...
}
use Module::Load::Conditional qw(check_install);
use if check_install(module => 'Clipboard') != undef, 'Clipboard'; # class methods: paste, copy
using if pragma and Module::Load::Conditional core module.
check_install returns hashref or undef.
this module is also mentioned in the see also section of the pragma's documentation:
Module::Load::Conditional provides a number of functions you can use to query what modules are available, and then load one or more of them at runtime.
This is an effective idiom for loading an optional module (so long as you're not using it in a code base with sigdie handler),
use constant HAS_MODULE => defined eval { require Module };
This will require the module if available, and store the status in a constant.
You can use this like,
use constant HAS_READLINE => defined eval { require Term::ReadKey };
my $width = 80;
if ( HAS_READLINE ) {
$width = # ... code, override default.
}
Note, if you need to import it and bring in the symbols you can easily do that too. You can follow it up.
use constant HAS_READLINE => defined eval { require Term::ReadKey };
Term::ReadKey->import if HAS_READLINE;
This method uses constants. This has the advantage that if you don't have this module the dead code paths are purged from the optree.
I think it doesn't work when using variables.
Please check this link which explains how it can be used with variable
$class = 'Foo::Bar';
require $class; # $class is not a bareword
#or
require "Foo::Bar"; # not a bareword because of the ""
The require function will look for the "Foo::Bar" file in the #INC array and will complain about not finding "Foo::Bar" there. In this case you can do:
eval "require $class";

Use a variable from one file into another

I have a variable $x which currently has a local scope in A.pm and I want to use the output of $x (which is usually PASSED/FAILED) in an if else statement in B.pm
Something like below
A.pm:
if (condition1) { $x = 'PASSED'; }
if (condition2) { $x = 'FAILED'; }
B.pm:
if ($x=='PASSED') { $y=1; } else { $y=0; }
I tried using require ("A.pm"); in B.pm but it gives me an error global symbol requires an explicit package name which means it is not able to read the variable from require. Any inputs would help
I have a variable $x which currently has a local scope in A.pm and I want to use the output of $x (which is usually PASSED/FAILED) in an if else statement in B.pm
We could show you how to do this, but this is a really bad, awful idea.
There's a reason why variables are scoped, and even global variables declared with our and not my are still scoped to a particular package.
Imagine someone modifying one of your packages, and not realizing there's a direct connection to a variable name $x. They could end up making a big mess without even knowing why.
What I would HIGHLY recommend is that you use functions (subroutines) to pass around the value you need:
Local/A.pm
package Local::A;
use strict;
use warnings;
use lib qw($ENV{HOME});
use Exporter qw(import);
our #EXPORT_OK = qw(set_condition);
sub set_condition {
if ( condition1 ) {
return "PASSED";
elsif ( condition2 ) {
return "FALSED";
else {
return "Huh?";
}
1;
Here's what I did:
I can't use B as a module name because that's an actual module. Therefore, I used Local::B and Local::A instead. The Local module namespace is undefined in CPAN and never used. You can always declare your own modules under this module namespace.
The use lib allows me to specify where to find my modules.
The package command gives this module a completely separate namespace. This way, variables in A.pm don't affect B.pm.
use Exporter allows me to export subroutines from one module to another. #EXPORT_OK are the names of the subroutines I want to export.
Finally, there's a subroutine that runs my test for me. Instead of setting a variable in A.pm, I return the value from this subroutine.
Check your logic. Your logic is set that $x isn't set if neither condition is true. You probably don't want that.
Your module can't return a zero as the last value. Thus, it's common to always put 1; as the last line of a module.
Local/B.pm
package Local::B;
use lib qw($ENV{HOME});
use Local::A qw(set_condition);
my $condition = set_contition();
my $y;
if ( $condition eq 'PASSED' ) { # Note: Use `eq` and not `==` because THIS IS A STRING!
$y = 1;
else {
$y = 0;
}
1;
Again, I define a separate module namespace with package.
I use Local::A qw(set_condition); to export my set_condition subroutine into B.pm. Now, I can call this subroutine without prefixing it with Local::A all of the time.
I set a locally scoped variable called $condition to the status of my condition.
Now, I can set $y from the results of the subroutine set_condition. No messy need to export variables from one package to another.
If all of this looks like mysterious magic, you need to read about Perl modules. This isn't light summer reading. It can be a bit impenetrable, but it's definitely worth the struggle. Or, get Learning Perl and read up on Chapter 11.
After you require A;, you can then access the variable by giving it an explicit package name like the error message says.
in B.pm:
my $y = $A::x eq 'PASSED ? 1 : 0
The variable $x will have to be declared with our instead of my.
Finally, use eq instead of == for doing string comparisons.

how Sub::Name set anonymous subroutine 's caller to NOT __ANON__?

I reading programming perl, at chapter 12, the objects, has following documents :
The next::method has a similar problems because it uses the package of
its caller to figure out what class to look at. If you define a method
in Donkey from another package, next::method will break:
package main;
*Donkey::sound = sub { (shift)–>next::method(#_) };
The anonymous subroutine shows up in the stack with as _ ANON _, so next::method doesn’t know which package it is in. You can use the Sub::Name CPAN module to make it work out, though:
use Sub::Name qw(subname);
*Donkey::sound = subname 'Donkey::sound' => sub { (shift)–>next::method(#_) };
I am very inquisitive how Sub::Name module complete this work ? let the anonymous subroutine's caller not be __ANON__
very thanks your help :)
From inside an anonymous subroutine you can achieve this by setting *__ANON__ to the desired name:
$sub = sub {
local *__ANON__ = 'Donkey::sound';
...
but Sub::Name sets it from the outside. A quick glance at the code leads me to think that it's poking and prodding the same stuff that setting *__ANON__ does, and you can't do that from perl code. It's in XS because it has to be, not because it's faster that way.

Is using __PACKAGE__ inside my methods bad for inheritance?

If inside my code I'll have calls like:
__PACKAGE__->method;
will this limit the usability of this module, if this module is inherited?
It depends on what you want to do:
#!/usr/bin/perl
package A;
use strict; use warnings;
sub new { bless {} => $_[0] }
sub method1 {
printf "Hello from: %s\n", __PACKAGE__;
}
sub method2 {
my $self = shift;
printf "Hello from: %s\n", ref($self);
}
package B;
use strict; use warnings;
use parent 'A';
package main;
my $b = B->new;
$b->method1;
$b->method2;
Output:
Hello from: A
Hello from: B
If you intend to inherit that method, call it on the referent and don't rely on the package you find it in. If you intend to call a method internal to the package that no other package should be able to see, then it might be okay. There's a fuller explanation in Intermediate Perl, and probably in perlboot (which is an extract of the book).
In general, I try not to ever use __PACKAGE__ unless I'm writing a modulino.
Why are you trying to use __PACKAGE__?
That depends. Sometimes __PACKAGE__->method() is exactly what you need.
Otherwise it's better to use ref($self)->class_method() or $self->method().
"It depends." is the correct answer. It is relatively uncommon to actually need the package name; usually you will have an instance or a class name to start with. That said, there are times when you really do need the package name -- __PACKAGE__ is clearly the tool for that job, being superior to a literal. Here are some guidelines:
Never call methods off __PACKAGE__ inside methods, as doing so makes it impossible for inheritors to change your implementation by simply overriding the called method. Use $self or $class instead.
Try to avoid __PACKAGE__ inside methods in general. Every use of __PACKAGE__ adds a little bit of inflexibility. Sometimes, inflexibility is what you want (because you need compile-time resolution or badly want to control where information is being stored), but be triply sure that what you want is worth the cost. You'll thank yourself later.
Outside of methods, you don't have access to a $self, and should call methods off __PACKAGE__ rather than a literal. This is mostly important for compile-time declarations like those provided by Class::Accessor.