why do I get no output, when I load this package (WinXP SP3, Strawberry Perl 5.18.1)?
package MY_TEST;
use warnings;
use strict;
use Win32::Console;
my $output;
$output ||= Win32::Console->new( STD_OUTPUT_HANDLE );
1;
Script:
#!/usr/bin/env perl
use warnings;
use strict;
use 5.10.0;
use MY_TEST;
say 'Hello World';
No output.
I have found a solution:
package MY_TEST;
use warnings;
use strict;
use Win32::Console;
my $output = Win32::Console->new( STD_OUTPUT_HANDLE );
$output->{handle} = undef;
1;
I suppose the problem is related to this Bug #33513.
Related
I want to use only the variable name from the another file.
test1.pl
use warnings;
use strict;
our $name = "hello world";
print "Helllloo\n";
test2.pl
use warnings;
use strict;
require "test.pl";
our $name;
print "$name\n";
test1.pl contain some content with many functions. I used the variable $name from the test1.pl. But Don't run test1.pl while running the test2.pl. For example when run the test2.pl it result was
Helllloo
hello world
That the Helllloo print from the test1.pl. How can use the another file variable name only How can i do it?
You should rewrite both test1.pl and test2.pl to use MyConfig, like this
test2.pl
use strict;
use warnings;
use MyConfig 'NAME';
print NAME, "\n";
MyConfig.pm
use strict;
use warnings;
package MyConfig;
use Exporter 'import';
our #EXPORT_OK = qw/ NAME /;
use constant NAME => "hello world";
1;
output
hello world
Use Const::Fast to export variables from a module:
use strict;
use warnings;
use My::Config '$NAME';
print "$NAME\n";
In My/Config.pm:
use strict;
use warnings;
package My::Config;
use Exporter 'import';
our #EXPORT = ();
our #EXPORT_OK = qw{ $NAME };
use Const::Fast;
const our $NAME => "hello world";
__PACKAGE__;
__END__
I have a main setup script which sets up the test env and stores data in some variables:
package main;
use Test::Harness;
our $foo, $xyz, $pqr;
($foo, $xyz, $pqr) = &subroutinesetup();
# ^ here
#test_files = glob "t/*";
print "Executing test #test\n";
runtests(#test_files);
In the test folder I have a testsuite (t/testsuite1.t, testsuite2.t etc.).
How can I access the value of $foo inside the testsuite1.t?
package main;
use Test::More;
$actual = getActual();
is($foo, $actual, passfoor);
# ^ here
done_testing();
Use Storable to store data in first script and retrieve it from other.
main.pl
($foo, $xyz, $pqr) = &subroutinesetup();
store ($foo, "/home/chankey/testsuite.$$") or die "could not store";
system("perl", "testsuite.pl", $$) == 0 or die "error";
testsuite.pl
my $parentpid = shift;
my $ref = retrieve("/home/chankey/testsuite.$parentpid") or die "couldn't retrieve";
print Dumper $ref;
You've received the $foo in $ref. Now use it the way you want.
You can't share a variable directly, because a new Perl process is started for each test file.
As noted in the documentation of Test::Harness, you should switch to TAP::Harness. It's more flexible: for example, it provides the test_args mechanism to pass arguments to test scripts.
$ cat 1.pl
#!/usr/bin/perl
use warnings;
use strict;
use TAP::Harness;
my $harness = 'TAP::Harness'->new({
test_args => [ qw( propagate secret ) ]
});
$harness->runtests('1.t');
__END__
$ cat 1.t
#!/usr/bin/perl
use warnings;
use strict;
use Test::More;
my %args = #ARGV;
is($args{propagate}, 'secret', 'propagated');
done_testing();
file1.pl
package ba;
#!/usr/bin/perl
use strict;
use warnings;
our $base_addr = 0x48;
file2.pl
package oa;
#!/usr/bin/perl
use strict;
use warnings;
our $offset_addr = 0;
file3.pl
#!/usr/bin/perl
do "file1.pl"
do "file2.pl"
my $final_val;
$final_val = $ba::base_addr + $oa::offset_addr;
printf "base_addr = 0x%0x\n", $ba::base_addr;
printf "offset_addr = 0x%0x\n", $oa::offset_addr;
printf "final addr = 0x%0x\n", $final_val;
ERRORS### ->
Argument "0x48" isn't numeric.
Use of uninitialized value.
Use of uninitialized value in addition.
Two major errors, both of which are found by using use strict; use warnings;. Always do so. (You used it in your modules, but not in your script.)
You correctly use $ba::base_addr in one spot, but then you proceeded to use non-existent variable $base_addr shortly afterwards.
You can only access $ba::base_addr as $base_addr if the current package is ba, or if you create an alias to it named $base_addr.
You either need to use $ba::base_addr consistently, or you need to export the variable to the using module. (This is one way to the alias I mentioned.)
You never assign a value to $ba::base_addr and $oa::offset_addr, so Perl gives you warnings when you attempt to add them ("not numeric") and when you try to print them ("uninitialized").
Some other problems we'll fix at the same time:
A module must return a true value, which is to say the last expression evaluated must evaluate to something true. It's thus standard to end a module with 1; (This applies to do too for reliable error detection: do $qfn or die $# || $!;.)
You should be using require instead of do since the files have a package declaration. It would be even better if you renamed them to .pm and used use.
The name of a module should match it's package declaration. If it contains package ba;, the file should be named ba.pm.
#! is only meaningful if 1) they are the first two characters of the file, and 2) if the file is provided to the OS for execution. Neither of those are the case for your modules.
ba.pm:
package ba;
use strict;
use warnings;
our $base_addr = 123;
1;
oa.pm:
package oa;
use strict;
use warnings;
our $offset_addr = 456;
1;
script.pl:
#!/usr/bin/perl
use strict;
use warnings;
use ba qw( );
use oa qw( );
my $final_val = $ba::base_addr + $oa::offset_addr;
print "base_addr = $ba::base_addr\n";
print "offset_addr = $oa::offset_addr\n";
print "final addr = $final_val\n";
You could avoid saying the package name everywhere if you exported the variables, and mentioned earlier.
ba.pm:
package ba;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( $base_addr );
our $base_addr = 123;
1;
oa.pm:
package oa;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( $offset_addr );
our $offset_addr = 456;
1;
script.pl:
#!/usr/bin/perl
use strict;
use warnings;
use ba qw( $base_addr );
use oa qw( $offset_addr );
my $final_val = $base_addr + $offset_addr;
print "base_addr = $base_addr\n";
print "offset_addr = $offset_addr\n";
print "final addr = $final_val\n";
It's typically bad form to export variables, though. It's usually far better to create accessors.
ba.pm:
package ba;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( base_addr );
my $base_addr = 123;
sub base_addr { $base_addr }
1;
oa.pm:
package oa;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( offset_addr );
my $offset_addr = 456;
sub base_addr { $base_addr }
1;
script.pl:
#!/usr/bin/perl
use strict;
use warnings;
use ba qw( base_addr );
use oa qw( offset_addr );
my $final_val = base_addr() + offset_addr();
print "base_addr = ".base_addr()."\n";
print "offset_addr = ".offset_addr()."\n";
print "final addr = $final_val\n";
You need to rename your files, add return values and include them using use. Here:
file1.pm
package ba;
use strict;
use warnings;
our $base_addr = 17;
1;
file2.pm
package oa;
use strict;
use warnings;
our $offset_addr = 19;
1;
file3.pl
#!/usr/bin/perl
use file1;
use file2;
my $final_val;
$final_val = $ba::base_addr + $oa::offset_addr;
print "base_addr = $ba::base_addr\n";
print "offset_addr = $oa::offset_addr\n";
print "final addr = $final_val\n";
Is it possible to access value of a global variable declared, in another perl script using require?
eg.
Config.pl
#!/usr/bin/perl
use warnings;
use strict;
our $test = "stackoverflow"
Main.pl
#!/usr/bin/perl
use warnings;
use stricts;
require "Config.pl"
print "$test\n";
print "$config::test\n";
sure. The way you have suggested almost works. Try:
Config.pl:
use warnings;
use strict;
our $test = "stackoverflow";
and the main program:
#!/usr/bin/perl
use warnings;
use strict;
require "Config.pl";
our $test;
print "$test\n";
When you call require, the file is executed in the same namespace as the caller. So without any namespaces or my declarations any variables assigned will be globals, and will be visible to the script.
You need to declare the variable $test in Main.pl by writing
our $test;
as you do in Config.pl. Then everything will work as you expect.
Better to use a module:
MyConfig.pm: (There's a core package called "Config" already.)
package MyConfig;
use strict;
use warnings;
use Exporter qw( import );
our #EXPORT_OK = qw( $test );
our %EXPORT_TAGS = ( ALL => \#EXPORT_OK );
our $test = "stackoverflow";
1;
main.pl:
use strict;
use warnings;
use MyConfig qw( :ALL );
print "$test\n";
I have two scripts and two conf file (actually perl scripts too):
conf1.pl
#some_array = ({name =>"orange", deny = > "yes"},
{name =>"apple", deny = > "no"});
conf2.pl
#some_array = ({name =>"male", deny = > "yes"},
{name =>"female", deny = > "no"});
script.pl
#!/usr/bin/perl -w
use strict;
our %deny = ();
call_another_script.pl_somehow_with_param conf1.pl
call_another_script.pl_somehow_with_param conf2.pl
foreach my $key (%deny) {
print $deny{$key},"\n";
}
another_script.pl
#!/usr/bin/perl -w
my $conf_file = shift;
do $conf_file;
foreach my $item (#some_array) {
print $item->{name},"\n";
if (defined $deny) {
$deny{$item{name}}++ if $item{deny} eq "yes";
}
}
I would like to call another_script.pl with conf filenames from script.pl so %deny will be visible in another_script.pl. And I dont wanna use Perl modules and I want to have scripts in separate files.
For example
./another_script.pl conf2.pl
and
./script
This problem is what modules are designed to solve. What you are asking is similar to "how do I conditionally execute code with out if?". We can tell you how to do it, but it isn't a good idea.
conf1.pl
#!/usr/bin/perl
use strict;
use warnings;
our #a = (1 .. 10);
conf2.pl
#!/usr/bin/perl
use strict;
use warnings;
our #a = ("a" .. "j");
master.pl
#!/usr/bin/perl
use strict;
use warnings;
our %deny;
do "conf1.pl";
do "child.pl";
do "conf2.pl";
do "child.pl";
use Data::Dumper;
print Dumper \%deny;
child.pl
#!/usr/bin/perl
use strict;
use warnings;
our %deny;
our #a;
for my $item (#a) {
$deny{$item}++;
}
From
http://www.serverwatch.com/tutorials/article.php/1128981/The-Perl-Basics-You-Need-To-Know.htm
Making Variables Global With Strict Pragma On
First you use:
use strict;
Then you use:
use vars qw( %hash #array);
This declares the named variables as package globals in the current
package. They may be referred to within the same file and package with their
unqualified names; and in different files/packages with their fully qualified
names.
That's all that I was needed!