如何从其他子例程访问哈希?

时间:2011-04-06 00:16:13

标签: perl selenium

我正在尝试为Web测试创建一些脚本,并使用以下代码从配置文件中设置变量:

package setVariables;
sub readConfig{
  open(FH, "workflows.config") or die $!;
  while(<FH>)
  {
    ($s_var, $s_val) = split("=", $_);
    chomp($s_var);
    chomp($s_val);
    $args{$s_var} = $s_val;
    print "set $s_var = $s_val\n";
  } 
  close(FH);
}

例如:var1 = val1              VAR2 = val2的              VAR3 = VAL3              等...

我希望能够将此子例程设置的值传递给另一个包中的子例程。这就是我想要传递给它的包。     package startTest;     使用setVariables;

sub startTest{
my %args = %setVariables::args;
my $s_var = $setVariables::s_var;
my $s_val = $setVariables::s_var;

setVariables::readConfig(); #runs the readConfig sub to set variables

my $sel = Test::WWW::Selenium->new( host => "localhost",
                                    port => 4444, 
                                    browser => $args{"browser"}, 
                                    browser_url => $args{"url"} );


$sel->open_ok("/index.aspx");
$sel->set_speed($args{"speed"});
$sel->type_ok("userid", $args{"usrname"});
$sel->type_ok("password", $args{"passwd"});
$sel->click_ok("//button[\@value='Submit']");
$sel->wait_for_page_to_load_ok("30000");
sleep($args{"sleep"});
}

不幸的是,它没有按原样保留变量,我不知道如何引用它们。 谢谢你的帮助。

4 个答案:

答案 0 :(得分:3)

您的代码存在一些问题。我们先解决这些问题。

# Package names should start with upper case unless they are pragmas.
package SetVariables;

# Do this EVERYWHERE.  It will save you hours of debugging.
use strict;
use warnings;

sub readConfig{

  # Use the three argument form of open()
  open( my $fh, '<', "workflows.config") 
    or die "Error opening config file: $!\n";

  my %config;

  # Use an explicit variable rather than $_
  while( my $line = <$fh> )
  {
    chomp $line;    # One chomp of the line is sufficient.
    ($s_var, $s_val) = split "=", $line;

    $config{$s_var} = $s_val;
    print "set $s_var = $s_val\n";
  }

  close $fh;

  return \%config;
}

然后像这样使用:

use SetVariables;

my $config = SetVariables::readConfig();

print "$_ is $config->{$_}\n" 
  for keys %$config;

但是,不要自己完成所有这些,请查看CPAN上的许多配置文件模块。考虑Config::AnyConfig::IniFilesConfig::JSON


您在评论中注意到您正在尝试使用多个文件,主要代码和一些软件包。

一种常见的模式是在主代码中加载配置并将其传递(或选择其中的元素)以消耗代码:

package LoadConfig;

sub read_config {
    my $file = shift;

    my $config;
    # Do stuff to read a file into your config object;

   return $config;
}

1;

同时在另一个文件中:

package DoStuff;

sub run_some_tests {
    my $foo = shift;
    my $bar = shift;

    # Do stuff here

    return;
}

sub do_junk {
    my $config;

    my $foo = $config->{foo};

    # Do junk

    return;
}

1;

在您的主脚本中:

use DoStuff;
use LoadConfig;


my $config = LoadConfig::read_config('my_config_file.cfg');

run_some_tests( $config->{foo}, $config->{bar} );
do_junk( $config );

所以在run_some_tests()中我从配置中提取了几个元素并单独传递它们。在do_junk()中,我只传入整个配置变量。

答案 1 :(得分:0)

您需要做的就是在散列中收集变量并在readConfig中返回对它的引用:

my %vars = ( var1 => val1,
             var2 => val2,
             var3 => val3,
           );

return \%vars;

并在startTest中:

my $set_vars = setVariables::readConfig();

答案 2 :(得分:0)

我建议使用常规格式(例如YAML)来存储配置数据。然后,您可以使用YAML::LoadFile读回配置数据的哈希引用,然后使用它。

或者,如果您不想将YAML或其他配置格式与预先编写的模块一起使用,则您需要在读取例程中实际返回散列或hashref。
如果您需要更多背景信息,请查看perlrefperlreftutperlintro

答案 3 :(得分:0)

您的用户是否会看到配置文件或只是程序员?如果它只是程序员,请将您的配置放在Perl模块中,然后使用use导入它。

在编译程序时,仅为程序员使用配置文件的唯一原因。由于Perl程序是脚本,因此不必担心解析配置文件的开销;就像Perl一样。

除非是您的用户,否则其格式比Perl简单。

PS:已经有一个名为Config的模块。打电话给你My_config并加载它:

use FindBin '$RealBin';
use lib $RealBin;
use My_config;

请参阅: perldoc FindBin perldoc Config