How do i load the package self in perl? - perl

Right now I'm trying to generate XML and print it out from Perl. I found this module, XML::Write, which looked rather nice. But when i wanted to try it out i ran in to some rather strange errors...
My test script looks like this
#!/usr/local/bin/perl -w
use strict;
use strict 'refs';
use XML::Writer;
my $writer = XML::Writer->new(OUTPUT => 'self');
$writer->xmlDecl("ISO-8859-1");
$writer->startTag("foo");
$writer->endTag("foo");
$writer->end;
print $writer->to_string;
and when I run it the only output is
Can't locate object method "print" via package "self" (perhaps you forgot to load "self"?) at /usr/lib/perl5/site_perl/5.8.8/XML/Writer.pm line 132.
What am I missing? Do i have to install some extra module to make the OO parts of perl avaliable? Should I somehow install an old version of XML::Write since I have a rather old Perl version?
Any help would be appreciated!

The special value self for the OUTPUT option of the constructor was added in v0.620. Previously, it expected an IO::Handle or a scalar reference.
Install the current version to be able to use this feature, or consult the documentation of the version you have installed (e.g. with command-line perldoc XML::Writer or by selecting your version in the “Go to version” drop-down list on the metacpan page.)
For your use case, you can supply a reference:
my $output;
my $writer = XML::Writer->new(OUTPUT => \$output);
...;
print $output;

I had a similar error message. My problem was that I was missing a $sign in the body of the module I was trying to load. There was an instruction self->... that should have been $self->....
I hope this helps

Related

Can't call method "text" on an undefined value at sample.pl line 11

use strict; # safety net
use warnings; # safety net
use feature 'say'; # a better "print"
use Mojo;
my $dom = Mojo::DOM->new;
my $ua = Mojo::UserAgent->new;
$dom= $ua->get('http://search.cpan.org/faq.html')->res->dom;
my $desc=$dom->at('#u')->text;
when I run this code the above error has occur . This is my input data form following web page pls refer this
I want output like this only answers.
CPAN Search is a search engine for the distributions, modules, docs, and ID's on CPAN. It was conceived and built by Graham Barr as a way to make things easier to navigate. Originally named TUCS [ The Ultimate CPAN Search ] it was later named CPAN Search or Search DOT CPAN.
If you are having technical difficulties with the site itself, send mail to cpansearch#perl.org and try to be as detailed as possible in your note describing the problem.
pls anyone can help me
Something like this:
perl -Mojo -le 'print r g("http://search.cpan.org/faq.html")->dom("#cpansearch > div.pod > p")->map("text")->to_array;'

How to create own module for reuse in Perl?

I wish to create my own module and I want to use that module name for further use. The main concept is: Create a module which should contain subroutines for line count, word-count and character count, and in main program I should use that module and I should read the file and the output should show me total number of lines, total number of words and total number of characters in that file.
package Countsample;
use strict;
use base"Exporter";
use 5.010;
our #EXPORT=qw/line_count/;
sub line_count
{my $line=#_;
return $line;
}
1;
This above doc is saved in Count.pm.
#!usr/bin/perl
use Countsample;
open FH,"text1.txt";
line_count();
print"$line\n";
The above code is saved in Count1.pl format.
I think this much information is enough to create, if you need any further information then let me know.
Kindly help me to create complete this task.
Let's start with the module. It was already mentioned, that it is common practice to name the file as the package it contains.
And there is a reason for this: using use with a name builds on the expectation that there will be a file somewhere in the path list (#INC) for modules by that name containing a matching namespace declaration (package whatever). This connection makes possible, what Exporter does in the first place.
http://perldoc.perl.org/Exporter.html
A more indepth but still succinct explanation of this can be found here
http://www.perlmonks.org/?node_id=102347
So the file would be named Countsample.pm:
package Countsample;
use strict;
use warnings;
use base "Exporter";
use 5.010;
our #EXPORT=qw/line_count/;
sub line_count
{
my ($fd) = (#_);
my $lines = 0;
while (<$fd>) {
$lines++
}
return $lines;
}
1;
I added use strict and use warnings to be notified about errors.
Then I changed the assignment of the arguments; the arguments in #_ are a list, so I assign those to a list on the left side (see the parentheses around $fd). You could use
my $fd = shift;
alternatively.
I chose to pass an open filehandle as an argument here, then count the lines, simply by reading the file linewise and returning the number of lines.
There are many ways to get the number of lines out of a file, just as a reference:
http://www.perlmonks.org/?node_id=538824
The main program then looks like this:
#!/usr/bin/perl
use v5.14;
use strict;
use warnings;
use Countsample;
open (my $fd, "<", "text1.txt");
say line_count($fd);
close($fd);
See http://perldoc.perl.org/functions/open.html for the ways to open a file that are available and preferable.
You really need to work on your question asking. You're not giving us enough to go on. You need to tell us:
Exactly what you want to do
Exactly what you have done
Exactly what expected behaviour you are seeing (including any error messages)
Let's step through getting past some of your errors.
Firstly, when I ran your program, I got this.
$ ./Count1.pl
bash: ./Count1.pl: usr/bin/perl: bad interpreter: No such file or directory
Ok, so that's just a stupid typo. But because you haven't explained what problems you are getting, we don't know if that's the problem you're seeing or whether you've introduced the typo when posting your question.
But it's easy to fix. The shebang line needs to be #!/usr/bin/perl. I'm pretty sure you had exactly the same typo in your last question!
Now what happens when I run your code.
$ ./Count1.pl
Can't locate Countsample.pm in #INC (you may need to install the Countsample module) (#INC contains: ...)
This is because your package doesn't have the same name as your module file. Why would you do that? It just complicates your life.
Ok, so let's fix the use statement so it's looking for the right thing - use Count.
Now I get a different error.
$ ./Count1.pl
Undefined subroutine &main::line_count called at ./Count1.pl line 5.
That's going to be a little harder to track down. So to make my life easier I'll turn on use strict and use warnings in both of the files.
I now get this:
$ ./Count1.pl
Global symbol "$line" requires explicit package name at ./Count1.pl line 9.
Execution of ./Count1.pl aborted due to compilation errors.
That means I'll need to declare the variable $line at some point so I'll add my $line just after the use Count line.
And now I get this:
$ ./Count1.pl
Name "main::FH" used only once: possible typo at ./Count1.pl line 8.
Undefined subroutine &main::line_count called at ./Count1.pl line 9.
At which point, I'm afraid, I get bored of digging. Had you presented us with this version of the code, then I might have had some energy left to investigate from here. But because I've spent ten minutes finding silly typos and fixing pointless bugs, I've lost all enthusiasm.
It's important to realise that the people here are all volunteers. We're happy to help you solve your problems, but you need to do some of the work yourself. You need to ensure that we don't waste time fixing obvious things that you could have found yourself. And you need to be a lot clearer than you have been so far when explaining what the problem is.
Here's the version of you code that I got to. Perhaps someone else will have the enthusiasm to take it to the next stage.
Count.pm
package Countsample;
use strict;
use warnings;
use base "Exporter";
use 5.010;
our #EXPORT = qw/line_count/;
sub line_count {
my $line = #_;
return $line;
}
1;
Count1.pl
#!/usr/bin/perl
use strict;
use warnings;
use Count;
my $line;
open FH,"text1.txt";
line_count();
print "$line\n";
Update: The "undefined subroutine" error was because I forgot to change the name of the package in Count.pm. Having done that I now get:
$ ./Count1.pl
Name "main::FH" used only once: possible typo at ./Count1.pl line 8.
Use of uninitialized value $line in concatenation (.) or string at ./Count1.pl line 10.
Which is the point at which you really need to start thinking about how your module works. What subroutines do you need? What parameters do they take? What do they return?

How to test your own Perl modules while not depending on other modules in production?

First of all, I think somebody needs to rewrite my question, I know what I am asking, not how I should ask it precisely.
Assume I have some local module LOCAL::Commons and it has one subroutine called globalTrim. I am testing that subroutine below, and while LOCAL::Commons is installed under /usr/local/lib/perl, the module I am testing below is located in directory /home/me/perl/LOCAL/. See how I am using use lib ... to make sure I am not using LOCAL::Commons located in /usr/local/lib/perl (I have this directory on my path).
Now, if LOCAL::Commons is using another local module LOCAL::Cool (that is, not from cpan), and I have also made some changes to that module, how can I make sure my tests are using the correct modules? That is, I want LOCAL::Commons to use /home/me/perl/LOCAL/Cool and not /usr/local/lib/perl/LOCAL/Cool.
#!/usr/bin/perl
# test_local_commons.pl
# directory: /home/me/perl
use strict;
use warnings;
use Test::More 'no_plan';
use File::Temp qw( tempfile tempdir );
use Cwd qw();
use lib Cwd::abs_path();
# Testing
use LOCAL::Commons qw ( globalTrim );
sub newTest($) {
my $name = shift;
print "---------------------------------------------------\n";
print $name, "\n";
print "---------------------------------------------------\n";
}
sub testTraverse {
is(globalTrim(" - stackoverflow - ), "-stackoverflow-", "Passed" );
}
newTest "testTraverse"; testTraverse ();
If you run this like so:
perl -I/home/me/perl test_local_commons.pl
It should ensure your /home/me/perl version is checked first
After you load the files you want, put this:
die 'Included PRODUCTION Module!!!'
if grep { m{/usr/local/lib/perl/LOCAL/Cool} } values %INC
;
Of course you could die for any module you wanted.
For example, we've got this tool at work that works with Activestate's PerlEZ.dll. We don't want to deploy it with Perl installed. But we need to use some libraries, which we hide elsewhere. When I'm testing my code I include a module from our hidden path. It blows up anytime it sees a standard library path in %INC. We want to make sure it almost everything from the #INC hook and the special libraries.
I suggest using Perlbrew to make a completely separate Perl installation for testing. That way you control the testing environment and don't really have to worry about it.
use lib has process scope -- that is, it changes the value #main::INC with global visibility, just as a non-localized assignment to #INC would. That means that any modules that you load after saying use lib will check the include path you've set.
As to what path use lib sets, it explicitly adds to the front of #INC so that later calls to use lib will be considered earlier when searching for modules.
The upshot of which is that it looks to me like your code sample will just work. Note that I'm going to discourage you from checking that you're using the under-development version in your test. That would cause your test to fail based on something unrelated to whether the function under test actually works correctly. (But note also that you should also have written unit tests for LOCAL::Cool.)
You could just add a BEGIN{ #INC = qw(directories you want to allow)} block. While using PERL5LIB, use lib etc. just appends to the include path, this will completely replace it, thus eliminating the danger that the module is picked up later in the search path, e.g. because you forgot to install it /home/me/perl/.
But the real TDD answer is probably to use mock modules for everything that's not the module under test.

why do i have to specify "use feature :5.1x" even when my installed perl is 5.14?

I have 5.14.2 installed in my machine but when i try to execute a print statement with say keyword it gives me error.
I have go with the use keyword to make the program run without error.
#!/usr/bin/perl
use feature ':5.10';
say "hello";
5.14.2 is latest when compared to 5.010 so it should have all those features enabled by default right ? then what is the point in specifying the version using use keyword ?
Perl attempts to maintain backward compatibility. It's quite possible that existing scripts might have subroutines named say. There is considerable on-going discussion of whether or not some future version of Perl should stop these efforts and streamline its internals. See, for instance, naming and numbering perl .
It prevents conflicts with existing programs written in Perl.
For example, say I wrote a program for Perl 5.6 which defined a subroutine called say.
use strict;
use warnings;
sub say { print 1; }
say();
That works fine (outputting 1), and it still works in perls that include the say feature.
Now let's enable the native say and see what happens:
use v5.14;
use strict;
use warnings;
sub say { print 1; }
say();
Now it falls over with *Use of uninitialized value $_ in say at - line 5.*
You need to use feature or use v5.xx so that the new features can be loaded safely, i.e. when the author knows he wants to use them.

How do I use a Perl package known only in runtime?

I have a Perl program, that needs to use packages (that I also write). Some of those packages are only chosen in Runtime (based on some environment variable). I don't want to put in my code a "use" line for all of those packages, of course, but only one "use" line, based on this variable, something like:
use $ENV{a};
Unfortunately, this doesn't work, of course. Any ideas on how to do this?
Thanks in advance,
Oren
eval "require $ENV{a}";
"use" doesn't work well here because it only imports in the context of the eval.
As #Manni said, actually, it's better to use require. Quoting from man perlfunc:
If EXPR is a bareword, the require assumes a ".pm" extension and
replaces "::" with "/" in the filename for you, to make it easy to
load standard modules. This form of loading of modules does not
risk altering your namespace.
In other words, if you try this:
require Foo::Bar; # a splendid bareword
The require function will actually look for the "Foo/Bar.pm" file
in the directories specified in the #INC array.
But if you try this:
$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" Statements are run at compilation time, not at run time. You will need to require your modules instead:
my $module = "Foo::Bar";
eval "require $module";
I would use UNIVERSAL::require. It has both require and use methods to use a package. The use method will also call import for the package.
use UNIVERSAL::require;
$ENV{a}->use or die 'Could not import package: ' . $#;
You probably want to use require instead of use if you don't want it to happen at compile time, and then manually import any symbols you might need. See this link to the Perl Cookbook (from Google Books) for a good discussion of methods you can use to achieve what you want.
I think that a module loaded in runtime can be a Plugin. I have this kind of problem, having specific modules to some cases that are loaded in run time as plugins with Module::Pluggable.
Maybe you need to change the logic of your modules, but it works and scale very well (my app started with four modules and now have twenty and it's growing).
How about using the core module Module::Load
With your example:
use Module::Load;
load $ENV{a};
"Module::Load - runtime require of both modules and files"
"load eliminates the need to know whether you are trying to require either a file or a module."
If it fails it will die with something of the like "Can't locate xxx in #INC (#INC contains: ...".
Many years later, eval "use $mod_name"; seems to work just fine (as of at least 5.8.8).
The advantage over eval "require $mod_name"; is that the loaded module's default exports are automatically imported; in other words:
eval "use $mod_name";
is the shorter equivalent of
eval "require $mod_name"; $mod_name->import();
Here's a test command, which passes the name of the module via env. variable mod_name, loads and imports the module, then uses an imported function (assumes a POSIX-like shell):
$ mod_name='Data::Dumper' perl -e 'eval "use $ENV{mod_name}"; print Dumper("hi!")'
$VAR1 = 'hi!';
I may be missing subtleties; if so, please let me know.