如何在RedHat上使用核心Perl打印变量及其值?

时间:2010-01-23 18:42:18

标签: perl

我正在尝试在Perl中创建一个简单的小子,最好不要使用标准RedHat linux发行版中没有的任何模块。换句话说,越便携越好,因为我不能总是控制我正在使用的系统环境。显而易见的问题是将变量传递给子程序,以便可以使用原始变量名和值。我可以得到一个或另一个,但无法弄清楚如何做这两个没有更复杂的子调用输入,如下所示。我可以传递一个字符串和一个引用,但这几乎就像在本地打印一样简单:

print "\$A = $A\n"; 

还有潜在的范围问题,但一次只能迈出一步。我现在想也许这不是那么简单。

(是的,这是我正在寻找的绝对懒惰的程序员代码)

伪代码示例:

my $A = 1;
my $secondVar = "something new";
my $XXX = 12345;

# Print a listing of the variables of interest in a nice easy to read listing
# with a minimum of typing. 

printVars( $A, $secondVar, $XXX ); 

# Note I could settle for passing by reference \$A but no more complicated than this in
# the sub call. This is just a little utility sub to use to double check variables while
# coding something new.

输出:

$A = 1
$secondVar = something new
$XXX = 12345

粗略的SUB:

sub printVars {
    my @ListOfVars = @_;
    my $i;
    my ($theVarName, $theVarValue);

    for( $i=0; $i<@ListOfVars; $i++) {
       $theVarName = ??;  # This is where things break down.
       $theVarValue = $ListOfVars[$i];
       print "$theVarName = $theVarValue\n";
    }
}

感谢您提供的任何帮助..

享受.. --Bryan

9 个答案:

答案 0 :(得分:4)

如果使用Paul Tomblin和john建议的变量名称的方法是可以接受的,您可能需要引入Data::Dumper模块以便能够打印出数据结构。

Data::Dumper长期以来一直是标准Perl5发行版的一部分(我刚刚在CPAN上验证过它已经在5.6,5.8和5.10中)。如果您的操作系统供应商没有以奇怪的方式将其分开,则无需担心Data::Dumper不在那里。

答案 1 :(得分:2)

这真的感觉就像你在这里重新发明轮子一样,所以我不得不问你的动机。有许多现有的机制可以帮助您调试代码,包括内置调试器(请参阅perldoc perldebugperldoc perldebugtut以获取手册和教程),以及{{3}处的大型模块库}。你正在考虑建立一个初学者的任何东西已经建成,所以除非你纯粹作为一种学习经历这样做,否则你应该使用已经可用的工具。

CPANData::Dumper是查看变量内部的常用方法,不仅仅是现在编码的简单字符串,还有深度和复​​杂的数据结构。 Data :: Dumper是许多标准Perl安装的一部分,但CPAN上分发的任何东西都可以安全依赖,因为它可以很容易地安装在您可能遇到的任何系统上。

答案 2 :(得分:2)

我不认为这可以在没有借助PadWalker的情况下对词法变量进行,因此您可能需要安装它。假设你可以,这是一个允许最少调用站点语法的工作解决方案。

use PadWalker qw/peek_my peek_our/;
use Data::Dumper;
$Data::Dumper::Indent = 0; # or however pretty you want

sub inspect {
    my $my  = peek_my  1;
    my $our = peek_our 1;

    for (split(/\s+/ => "@_")) {
        my $val = $$my{$_} || $$our{$_} 
                           || die "$_ not found";
        print Data::Dumper->Dump(
            /^\$/ ? ([$$val], [$_])
                  : ([ $val], ['*' . substr $_, 1])
        ) . "\n";
    }
}

sub foo {
    my $bar = shift;
    inspect '$bar';
}

{ # closed scope
    my $x = 'hello, world!';
    my $y;
    my @z = 1 .. 10;
    our %global = (a => 1, b => [1 .. 3]);
    my $ref = \%global;

    inspect '$x $y @z %global $ref';  # qw/.../ can be used also
    foo;
    foo $x;
}

打印出来

$x = 'hello, world!';
$y = undef;
@z = (1,2,3,4,5,6,7,8,9,10);
%global = ('a' => 1,'b' => [1,2,3]);
$ref = {'a' => 1,'b' => [1,2,3]};
$bar = undef;
$bar = 'hello, world!';

答案 3 :(得分:1)

您可以将变量名称作为标量传递,然后使用引用来打印出值。来自perlref:

1.  $name = "foo";
2. $$name = 1; # Sets $foo
3. ${$name} = 2; # Sets $foo
4. ${$name x 2} = 3; # Sets $foofoo
5. $name->[0] = 4; # Sets $foo[0]
6. @$name = (); # Clears @foo
7. &$name(); # Calls &foo() (as in Perl 4)
8. $pack = "THAT";
9. ${"${pack}::$name"} = 5; # Sets $THAT::foo without eval

答案 4 :(得分:1)

传入变量名称列表,然后使用

打印出来
foreach $varname (@list)
{
   print "$varname = $$varname\';
}

实际上,要想到它,那也行不通,因为$$不会起作用,因为sub不知道变量。我不认为你能做你想做的事情,除了把所有变量名和值放入哈希并用Data :: Dumper转储它们。通常在这一点上我会删除这个答案,但其他几个人已经引用了它,所以我不会。

use Data::Dumper;
print Dumper({"a" => $a, "cVar" => $cVar});

会产生类似的东西:

$VAR1 = {
          'a' => 'foo',
          'cVar' => 'this is cVar'
        };

答案 5 :(得分:1)

有关将变量用作变量名的观点,请参阅How can I use a variable as a variable name?。否则你必须使用john和Paul Tomblin建议的参考文献。

答案 6 :(得分:1)

没有子,但我建议Smart::Comments。就这么简单:

use Smart::Comments;
### $A

$A将显示在它的所有荣耀中,如果1)它没有动态循环(如某些Win32 :: OLE对象那样),或者如果2)它不是“由内而外的对象” ,它是指向数据键的指针,而不是数据本身。输出比Data::Dumper更具可读性(它在幕后使用Data::Dumper,因此DD全局变量可用,如$Data::Dumper::Deparse(在链表的底部),用于打印输出字幕。

如果您不想打印出来的内容,请注释掉use声明。然后,他们只是评论。

它也很便携。我只是简单地将Text :: Balanced和Smart :: Comments从我的PC移植到了AIX盒子里。完成。

答案 7 :(得分:0)

# A sub to print the value of any variable, scalar, array, or hash
sub strv
{ # edit structured things as a string for debugging
  my ($v,$d) = @_;
  my $s = '';

  $d = 0 if not defined $d;

  if (not defined $v)
  {
    $s.= (' 'x$d)."N";
  }
  elsif (ref($v) eq 'SCALAR')
  {
    if (! defined $$v)
    {
      my $null = 'NULL';
      $v = \$null;
    }
    $s.= (' 'x$d)."S:$$v";
  }
  elsif (ref($v) eq 'ARRAY')
  {
    $s.= (' 'x$d)."A:(";

    my $c = '';
    my $x = 0;

    foreach my $a (map(strv($_,0),@{$v}))
    {
      $s.= "$c$x:$a";
      $c = ',';
      $x++;
    }
    $s.= ")";
  }
  elsif (ref($v) eq 'HASH')
  {
    $d++;
    $s.= "\n" if $s ne '';
    while( my ($k, $x) = each %{$v} ) {
      $s.= (' 'x$d)."H:".strv($k,$d+1).": ".strv($x,$d+1)."\n";
    }
    $s = substr($s, 0, -1);
  }
  elsif (ref($v))
  {
    $s.= ref($v);
  }
  $s.= (' 'x$d).'"'.$v.'"' if ref($v) eq '';
  return $s;
} # sub strv

答案 8 :(得分:0)

这里的记录是几个人建议的实际解决方案的一个例子 你使用Data :: Dumper。希望它可以帮助任何人寻找一个简单的子 以非常小的努力来打印变量。谢谢大家!!

#!/usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;

my @myArray = qw ( a b c d e f g h i j k );

# Showing Difference between shift and pop and what happens to @myArray
my ($A, $B, $C, $D,);

$A = shift @myArray;
$B = pop   @myArray;
$C = shift @myArray;
$D = pop   @myArray;

# prtVar() usage is close to original desired simplicity 
# only needed to add the qw() 

prtVar(qw ($A $B $C $D));

sub prtVar
    {
    my (@vars) = @_;
    my $vname;

    foreach $vname (@vars)
        {
        print Data::Dumper->Dump([eval($vname)], [$vname]);
        }
    }

输出:

$A = 'a';
$B = 'k';
$C = 'b';
$D = 'j';