what does perl use Cwd qw(); mean? - perl

What does
use Cwd qw();
mean in perl?
I know qw gives quotes to each elements inside ()
But what about this case?

The qw() is a fancy way of writing an empty list. Doing () would be two characters shorter.
Passing an empty list to use is important to avoid importing. From the use documentation:
If you do not want to call the package's import method (for instance, to stop your namespace from being altered), explicitly supply the empty list
E.g. by default, the Cwd module exports getcwd. This doesn't happen if we give it the empty list:
use strict;
use Cwd;
print "I am here: ", getcwd, "\n";
works, but
use strict;
use Cwd ();
print "I am here: ", getcwd, "\n";
aborts compilation with Bareword "getcwd" not allowed while "strict subs" in use.

I believe that since qw() after use Module is for importing subroutines, when left empty it simply loads the module but doesn't import any subroutines into the namespace.
For example this throws an error since getcwd is not imported:
#!/usr/bin/perl
use warnings;
use strict;
use Cwd qw();
my $dir=getcwd;
But I'm not sure if this is the answer you was looking for..!

Usually it "imports" commands so you don't have to create an object and call the function on them.
Example (from perlmonks):
#without qw
use CGI;
my $q = CGI->new();
my $x = $q->param('x');
#with qw
use CGI qw/:standard/;
my $x = param("x")
Source: http://www.perlmonks.org/?node_id=1701
Most modules have import groups like :all or :standard also.

Related

Program unexpectedly reports "Use of uninitialized value"

This is with regard to my previous question
Hold Subroutine response and set to variable in Perl
The statement Module::thesub("hello")
worked in Module.pm but fails if I move it to main.pl
main.pl
#!/usr/bin/perl
use strict;
use warnings;
use Module;
Module::thesub("hello");
Module.pm
#!/usr/bin/perl
use strict;
use warnings;
package Module;
sub thesub {
state $stored;
$stored = shift if #_;
return $stored;
}
my $testvar = thesub();
print $testvar;
1;
I get this error
Use of uninitialized value $testvar
which means the variable $testvar has no value.
How can I fix this?
Statements in a module run when the module is loaded, at use Module;. At that time thesub() still wasn't called with an argument and $stored in it is undefined. So that is what $testvar gets when it's assigned and the warning is emitted when it's printed.
The $testvar can be used in main
use strict;
use warnings;
use Module;
Module::thesub("hello");
my $testvar = Module::thesub();
even though I am not sure from the question what the purpose of this is.
Remove the assignment and print of $testvar from the module. Note that you'll also need use feature 'state'; at the beginning of the module, to enable the feature pragma.
A few comments on the module you show
No need for #!/usr/bin/perl, as a module is generally not meant to be run
The package Module; is commonly the first line
While what you have works, consider making symbols from the module available to the calling code, so that it can import them and simply say thesub(). A common way is
package Module;
use warnings;
use strict;
use Exporter qw(import);
our #EXPORT_OK = qw(thesub);
sub thesub { ... }
1;
and in the main
use Module qw(thesub);
thesub("hello");
See Exporter for starters and search SO, where there are great many posts on this.

Importing variable into Perl package

I'm writing a basic program whose core logic is split across several project-specific modules for cleanliness (keeping subroutines organised by their purpose in the program's logic).
Suddenly had trouble exposing an option from the main package in one of the modules, and using the our statement appeared to have no effect.
For brevity, I'll copy+paste an isolated test case I wrote to examine this behaviour:
main.pl
#!/usr/bin/perl
use warnings;
use strict;
use File::Basename;
# The variable to be read by the module.
our $verbose = 1;
# Load Output.pm from directory
use lib dirname "$0";
use Output;
write_message "Hello, world\n";
Output.pm
package Output;
use warnings;
use strict;
use parent "Exporter";
our #EXPORT = qw(write_message);
# Should be imported?
our $verbose;
sub write_message {
print $_[0] unless !$verbose;
}
1;
Expected result: "Hello, world"
Actual result: Dead silence
It's quite possible that what I'm trying to achieve isn't even possible in Perl, as this isn't the intended use of modules (and heck, I understand why that'd be the case).
I'm still quite new to Perl and there are some things I'm struggling to wrap my head around. I've seen people recommend using the our declarator to expose a variable across packages, but I can't understand why this isn't working.
PS: If anybody knows a better approach to splitting an app's program-specific logic between modules, I'd appreciate some pointers too. :) But first and foremost, I'd prefer to learn why our-ing a variable isn't working.
An our statement just creates a package variable (whereas my creates a lexical variable). It has nothing to do with exporting
The best option is probably to declare the variable in the Output package and access it as $Output::verbose elsewhere. Like this
main.pl
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use lib dirname $0;
use Output;
$Output::verbose = 1;
write_message "Hello, world\n";
Output.pm
package Output;
use strict;
use warnings;
use Exporter 5.57 'import';
our #EXPORT = qw/ write_message /;
our $verbose;
sub write_message {
print $_[0] if $verbose;
}
1;
Note that I have also removed the incorrect quotes from around $0, and ever since version 5.57 of Exporter it has been possible (and preferable) to import it's import subroutine instead of subclassing it
our declares a package variable in the current package. The one in main.pl refers to $main::verbose; the one in Output.pm refers to $Output::verbose.
You can use the full name $main::verbose to access the variable from anywhere, but you can't really "export" it because exporting refers to making symbols accessible to users of your module. You're trying to do the opposite.

perl - File::Basename->fileparse returns "File::Basename"

For some reason my code is doing this wierd thing where fileparse only prints (literally) File::Basename
use strict;
use warnings 'all';
use File::Basename;
...
my $fileName = File::Basename->fileparse($filePath);
print("$filePath\n");
print("$fileName\n");
And output is:
a/b/c/d.bin
File::Basename
What did I do wrong?
The fileparse is not a method; it is a function. This function is exported by default, so you actually want to do
use File::Basename;
my $fileName = fileparse($filePath);
You have used is as a method call. Here File::Basename->fileparse($filePath) is equivalent to
fileparse("File::Basename", $filePath)
because in a method invocation, the invocant (usually an object; here the package name) becomes the first argument. This is wrong, as it treats "File::Basename" as the path to parse, and the following arguments as a list of valid suffixes.
If you want to use the fileparse function without exporting it to your namespace, you could
use File::Basename (); # note empty parens that supress the import
File::Basename::fileparse(...); # use fully qualified name

How to use a module in Perl

Guys im really confused on how to use a module i just installed in Perl.
I installed a Corelist module in Perl. And i want to display all the modules that came with Perl 5.006. But there is a hint in doing this by using this code which i dont understand:
my %modules = %{ $Module::CoreList::version{5.006} };
But when i did this
#! usr/bin/perl
use warnings;
use strict;
my %modules = %{$Module::CoreList::version{5.006}};
print %modules;
it gives this error: Module::CoreList::version used only once . I also tried putting
use Module::CoreList; still no luck
The name of the module is 'Module::CoreList'. You should put the following line into your programme:
use Module::CoreList;
Also note the capital L. Perl is case sensitive.
If you simply want to print the hash, just add Data::Dumper module along with strict and warnings, then
print Dumper(\%modules);
Updated: try something like
use warnings;
use strict;
use Module::CoreList;
use Data::Dumper;
my %module = %{ $Module::CoreList::version{5.006} };
print Dumper (\%module);

How to share/export a global variable between two different perl scripts?

How do we share or export a global variable between two different perl scripts.
Here is the situation:
first.pl
#!/usr/bin/perl
use strict;
our (#a, #b);
.........
second.pl
#!/usr/bin/perl
use strict;
require first.pl;
I want to use global variable (#a, #b) declared in first.pl
Also,suppose there's a variable in second perl file same as first perl file. But I want to use first file's variable. How to achieve this?
In general, when you are working with multiple files, and importing variables or subroutines between them, you will find that requiring files ends up getting a bit complicated as your project grows. This is due to everything sharing a common namespace, but with some variables declared in some files but not others.
The usual way this is resolved in Perl is to create modules, and then import from those modules. In this case:
#!/usr/bin/perl
package My::Module; # saved as My/Module.pm
use strict;
use warnings;
use Exporter;
our #ISA = 'Exporter';
our #EXPORT = qw(#a #b);
our (#a, #b);
#a = 1..3;
#b = "a".."c";
and then to use the module:
#!/usr/bin/perl
use strict;
use warnings;
use My::Module; # imports / declares the two variables
print #a;
print #b;
That use line actually means:
BEGIN {
require "My/Module.pm";
My::Module->import();
}
The import method comes from Exporter. When it is called, it will export the variables in the #EXPORT array into the calling code.
Looking at the documentation for Exporter and perlmod should give you a starting point.
They will share global variables, yes. Are you seeing some problem with that?
Example:
first.pl:
#!/usr/bin/perl
use strict;
use warnings;
our (#a, #b);
#a = 1..3;
#b = "a".."c";
second.pl:
#!/usr/bin/perl
use strict;
use warnings;
require "first.pl";
our (#a,#b);
print #a;
print #b;
Giving:
$ perl second.pl
123abc
Cant you use package and export the variable?