我正在尝试在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
答案 0 :(得分:4)
如果使用Paul Tomblin和john建议的变量名称的方法是可以接受的,您可能需要引入Data::Dumper
模块以便能够打印出数据结构。
Data::Dumper
长期以来一直是标准Perl5发行版的一部分(我刚刚在CPAN上验证过它已经在5.6,5.8和5.10中)。如果您的操作系统供应商没有以奇怪的方式将其分开,则无需担心Data::Dumper
不在那里。
答案 1 :(得分:2)
这真的感觉就像你在这里重新发明轮子一样,所以我不得不问你的动机。有许多现有的机制可以帮助您调试代码,包括内置调试器(请参阅perldoc perldebug和perldoc perldebugtut以获取手册和教程),以及{{3}处的大型模块库}。你正在考虑建立一个初学者的任何东西已经建成,所以除非你纯粹作为一种学习经历这样做,否则你应该使用已经可用的工具。
CPAN和Data::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';