Perl:Undefined subroutine &main - perl

One of my non-developer friend asked my help about that issue. I am a windows developer, i don`t know anything about Perl, also script languages. I tried to search the issue but could not find a solution. Is there anyone can tell me what is the problem here and how to fix it.
Error after clicking the button:
Undefined subroutine &main::quote_javascript called at /usr/libexec/webmin/chooser.cgi line 192.
And the line 192 is :
$link = "<a href=\"\" onClick='fileclick(\"".&quote_javascript("$dir$f")."\", $isdir); return false'>";

The code that's actually triggering the error is of the form
... quote_javascript(...) ...
You are calling a sub named quote_javascript (in the current package, main). There is no sub named quote_javascript (in the current package, main).

Related

Perl Net::Appliance::Session waitfor?

I have a problem with Net::Appliance::Session. I created a session, executed my command. After execution it prompts me some question (yes/no). I want to answer it but didn't find a way how to do it. Below you can see my trials:
$session->cmd($command);
$session->waitfor(Match=>'/.*yes*/');
$session->print("no");
$session->waitfor(Match=>'');
$session->print("y");
I don't know where is the problem. Accoding to CPAN documentations Net::Telnet have the method waitfor. But Session documentation tells that we can use waitfor(). Another thing said there is that the method "cmd" have a member Match which includes all the features of waitfor(). So I changed my code like below:
$session->cmd($command, Match=>'/.*yes*/');
$session->print("no");
Executing this reports below error:
Odd number of elements in hash assignment at
/usr/lib/perl5/vendor_perl/5.8.8/Net/Appliance/Session.pm line 245.
Is there any idea how can I do that? And why am I getting this error message?
Thanks in advance..
From the Net::Appliance::Session page at meta::cpan
To handle more complicated interactions, for example commands which prompt for confirmation or optional parameters, you should use a Macro. These are set up in the phrasebook and issued via the $s->macro($name) method call. See the Phrasebook and Cookbook manual pages for further details.
So you set up a macro (scripted call and response) in a phrasebook, and then tell your session to use that macro.

How can I fix `"main::HKEY_LOCAL_MACHINE" used only once` warnings when using Perl's Win32::Registry?

I have a script that would get a registry key value. Here's the code.
use strict;
use warnings;
my $winRegistryStatus=0;
eval {
require Win32::Registry;
Win32::Registry->import();
};
unless($#) {
$winRegistryStatus=1;
}
my $registryPath = "Self\Random";
my $keyName = "Configure";
my $registryKeySettings;
my %registrySubKeyValues;
$main::HKEY_LOCAL_MACHINE->Open($registryPath, $registryKeySettings) || die "Cannot open $registryPath: $!";
$registryKeySettings->GetValues(\%registrySubKeyValues); # get sub keys and value -hash ref
foreach my $subKey (keys %registrySubKeyValues) {
my $_subKey = $registrySubKeyValues{$subKey};
next unless $$_subKey[0] eq $keyName;
print "Configure=" . $$_subKey[2];
}
Output
Name "main::HKEY_LOCAL_MACHINE" used only once: possible typo at ....
Configure=Yes
I could get the value of Configure but it also returns a warning which I don't know how to fix it.
Any body where am I wrong and could show me how to fix it?
Thanks.
The "used only once" is a warning that use warnings issues because you have used $main::HKEY_LOCAL_MACHINE only once. You are not at fault here. It is a mere hint that you might have forgotten something.
In this case, you can either ignore it, or simply deactivate that kind of warning: no warnings 'once'.
In general it is a good idea to enclose these things in a BLOCK and add a long, descriptive comment to it that explains why you are turning off that kind of warning here.
{ # Disable 'used only once' warning because the $::HKEY_...
# var was imported by Win32::Registry and is not used anywhere else.
$main::HKEY_LOCAL_MACHINE->Open($registryPath, $registryKeySettings)
|| die "Cannot open $registryPath: $!";
}
You can find more infos about warnings here.
This module is rather odd in that it exports symbols to the main package regardless of where it is used from.
But in your case this is what you want: your program is in main as you have no package statement, and you can omit the main:: from $HKEY_LOCAL_MACHINE.
As to your problem, the code you show doesn't raise the warning you say it does. The problem must be somewhere else. Please would you show your full code so that we can advise you better.
In the mean time please pay heed to #Sinan Ünür's advice - Win32::TieRegistry is preferable to Win32::Registry. Even the POD documentation of Win32::Registry says this:
NOTE: This module provides a very klunky interface to access the
Windows registry, and is not currently being developed actively. It
only exists for backward compatibility with old code that uses it. For
more powerful and flexible ways to access the registry, use
Win32::TieRegistry.
Update
I understand the problem having seen the update to your question and it is because you are executing the require Win32::Registry at run time. That means that $HKEY_LOCAL_MACHINE doesn't exist at compile time and so the compiler complains about it.
The fix is to declare it at compile time with
our $HKEY_LOCAL_MACHINE
at the top of the program.
By the way there is no need for the import call if all you need is this scalar.

Selenium WebDriver with Perl

I am trying to run the Selenium driver with Perl bindings, and due to the lack of examples and documentation, I am running into some roadblocks. I have figured out how to do some basic things, but I seem to be running into some issues with other simple things like validating the text on a page using Remote::Driver package.
If I try to do something like this:
$sel->get("https://www.yahoo.com/" );
$ret = $sel->find_element("//div[contains( text(),'Thursday, April 26, 2012')]");
I get a message back that the element couldn't be found. I am using xpath because the driver package doesn't appear to have a sub specific for finding text.. at least not that I've found.
If my xpath setup is wrong or if someone knows a better way, that would be extremely helpful. I'm having problems with some button clicking too.. but this seems like it should be easier and is bugging me.
Finding text on a web page and comparing that text to some "known good value" using Selenium::Remote::Driver can be implemented as follows:
File: SomeWebApp.pm
package SomeWebApp;
sub get_text_present {
my $self = shift;
my $target = shift;
my $locator = shift;
my $text = $self->{driver}->find_element($target, $locator)->get_text();
return $text;
}
Somewhere in your test script: test.pl
my $text = $some_web_app->get_text_present("MainContent_RequiredFieldValidator6", "id");
The above finds the element identified by $target using the locating scheme identified by $locator and stores it in the variable $text. You can then use that to compare / validate as required / needed.
https is a tad slower loading than http. Although WebDriver is pretty good about waiting until it's figured out that the requested page is fully loaded, maybe you need to give it a little help here. Add a sleep(2); after the get() call and see if it works. If it does, try cutting down to 1 second. You can also do a get_title call to see if you've loaded the page you think you have.
The other possibility is that your text target isn't quite exactly the same as what's on the page. You could try looking first for one word, such as "April", and see if you get a hit, and then expand until you find the mismatch (e.g., does this string actually have a newline or break within it? How about an HTML entity such as a non-breaking space?). Also, you are looking for that bit of text anywhere under a div (all child text supposedly is concatenated, and then the search done). That would more likely cast too wide a net than not get anything at all, but it's worth knowing.

Erroring in my Perl script coming from CAM::PDF::Annot module. Don't know why

I believe this may be a bug in the module I am using, or I am just completely overlooking something.
My code is this:
#!/usr/bin/perl
use strict;
use warnings;
use CAM::PDF;
use CAM::PDF::Annot;
sub main()
{
my $pdf = CAM::PDF::Annot->new( 'b.pdf' );
my $otherDoc = CAM::PDF::Annot->new( 'b_an.pdf' );
my $page = 1;
my %refs;
my #list = #{$pdf->getAnnotations($page)};
for my $annotRef (#list){
$otherDoc->appendAnnotation( $page, $pdf, $annotRef, \%refs);
}
$otherDoc->output('pdf_merged.pdf');
}
exit main;
This code was taken almost directly from the synopsis found on the module's CPAN page: http://metacpan.org/pod/CAM::PDF::Annot
The problem comes when I run the script using TWO pdf's with annotations. Using two pdf's without annotations runs. Using one pdf with annotations, and one pdf without annotations, runs. Only when both pdf's have annotations does it error.
The error is: "Can't use string ("46") as an ARRAY ref while "strict refs" in use at /usr/opt/perl5/lib/site_perl/5.10.1/CAM/PDF/Annot.pm line 195"
Line 195 of Annot.pm is:
push #{$annots->{value}}, $pupRef;
Annot.pm is inside the CAM::PDF::Annot module.
Any guidance in fixing this would be greatly appreciated!
P.S. In the error, "string ("x")", x is always a number, and seems to change depending on the pdf and the annotations within the pdf.
And I will try to add any other information that you need to help figure this out!
Whenever I have a problem with a CPAN module, I go to its webpage to try and assess its quality and see if any bugs have already been reported.
http://search.cpan.org/~donatoaz/CAM-PDF-Annot-0.06 shows the following suspicious results:
CPAN Testers PASS (2) FAIL (168) NA (49)
It is surprising that you were able to install the module. No one has reported bugs, but there is clearly a major problem with the code. It seems the author is either unaware of the tester reports (which have been sent to his CPAN email address for more than a year), or has stopped maintaining it.
You could submit a bug report, so at least others will be aware of your issue.
I realize this does not answer your question of how to fix the problem, but even if you do identify a fix, the author may not apply it (in which case, someone could start the process of becoming a co-maintaner).

Ways to call Blocks within Magento: createBlock vs Layout xml file

Context: I'm trying to include Adminhtml blocks in the frontend of the site to replace some of the user account blocks. The first thing I'm trying to do is simply display the block on the correct page. I can replace the entire page by setting the Body of the response inside the controller, but I'm having a hard time including the block in the layout xml file and then calling it within the template.
This block's default template is adminhtml/default/default/widget/grid.phtml. So I have placed widget/grid.phtml and widget/grid/ folder (needed by widget/grid.phtml) inside of the frontend theme.
I'm using community edition v1.3.2.2
Why would I be able to create an adminhtml/sales_order_grid from Mage_Sales_OrderController using createBlock:
$this->getResponse()->setBody($this->getLayout()->createBlock('adminhtml/sales_order_grid')->toHtml());
But not from a frontend layout, using a declaration
<sales_order_history>
<reference name="content">
<block type="adminhtml/sales_order_grid" name="orders_widget"/>
</reference>
</sales_order_history>
within app/design/frontend/default/default/layout/sales.xml
The latter produces an error without a stack trace:
Fatal error: Call to a member function toHtml() on a non-object in app/code/core/Mage/Core/Model/Layout.php on line 526
That line is the function getOutput() that Alan refers to below. The data in callback[0] is blank. As far as I can tell, it's null. When output to a log, it's blank. get_class(callback[0]) returns nothing discernable as well.
As far as I can tell, no blocks are rendered. There is nothing shown in the browser except the error message. In the log, the only output from the getOutput() method within app/code/core/Mage/Core/Model/Layout.php is the one where it breaks - no block name in callback[0].
However, I do know that _prepareCollection on the sales_order_grid block is being called.
Update: It turns out that I can get the block to render by adding it to the layout file. The call that throws the error is in app/code/core/Mage/Sales/controllers/OrderController.php in public function historyAction(). The call to $this->renderLayout() is what causes the problem. Evidently, I can't have both the grid block and the history template rendered in the same action. I'm not sure why though.
Thanks for any guidance!
More details about the other customizations you've done to get yourself to this point might help people troubleshoot your problem. When I tried your "create the block programmatically" code I got the following error.
Warning: include(/path/to/magento1point4.dev/app/design/frontend/base/default/template/widget/grid.phtml) [function.include]: failed to open stream: No such file or directory in /path/to/magento1point4.dev/app/code/core/Mage/Core/Block/Template.php on line 189
I added a simple phtml template to the above location and was able to insert the block via a layout file succfully after that
<reference name="content">
<block type="adminhtml/sales_order_grid" name="orders_widget"/>
</reference>
So I suspect something you've done along the way already is tripping things up.
Also, a Magento version would help things. Line 526 of the current version of community edition is a comment.
All that said my best guess is things are failing in the getOutput method of the Layout class. I'd add some logging to the function on your dev server to see what Magento is trying to do/instantiate when it bails on you.
public function getOutput()
{
$out = '';
if (!empty($this->_output)) {
foreach ($this->_output as $callback) {
Mage:Log('Trying to get the block ' . $callback[0] . ' and call its ' . $callback[1] . 'method');
$out .= $this->getBlock($callback[0])->$callback[1]();
}
}
return $out;
}