Как я могу напечатать переменную и ее значение только с основным Perl на RedHat? - PullRequest
2 голосов
/ 23 января 2010

Я пытаюсь создать то, что должно быть простым маленьким сабвуфером в 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 ]

4 голосов
/ 23 января 2010

Если подход с использованием имен переменных, предложенных Полом Томблином и Джоном, является приемлемым, вы можете использовать модуль Data::Dumper, чтобы иметь возможность распечатывать структуры данных.

Data::Dumper долгое время был частью стандартного дистрибутива Perl5 (я только что проверил на CPAN, что он был в 5.6, 5.8 и 5.10). Если ваш поставщик ОС не занимался этим странным образом, вам не нужно беспокоиться о том, что Data::Dumper не будет там.

2 голосов
/ 26 января 2010

Я не думаю, что это можно сделать для лексических переменных, не прибегая к 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!';
2 голосов
/ 23 января 2010

Такое ощущение, что вы пытаетесь изобрести колесо здесь, поэтому я должен спросить вас о ваших мотивациях. Существует множество существующих механизмов для помощи в отладке кода, включая встроенный отладчик (см. perldoc perldebug и perldoc perldebugtut для руководства и учебного пособия), а также гигантскую библиотеку модули на CPAN . Все, что вы думаете о создании в качестве новичка, уже создано, поэтому, если вы не делаете это исключительно в качестве учебного процесса, вам следует использовать инструменты, которые уже доступны для вас.

Data :: Dumper и Data :: Dump - это обычные способы просмотра внутренних элементов переменной, не просто простых строк, которые вы сейчас кодируете, но и глубоких и сложных структуры данных. Data :: Dumper является частью многих стандартных установок Perl, но все, что распространяется на CPAN, безопасно полагаться, поскольку его легко установить в любой системе, с которой вы можете столкнуться.

1 голос
/ 23 января 2010

Нет саба, но я рекомендую Smart::Comments. Это так просто:

use Smart::Comments;
### $A

$A будет показано во всей красе, если 1) у него нет динамического цикла (как это делают некоторые объекты Win32 :: OLE), или, если 2), это не «объект наизнанку», который это указатель на ключ к данным, а не сами данные. Выходные данные даже более читабельны, чем Data::Dumper (он использует Data::Dumper за кулисами, поэтому можно использовать глобальные переменные DD, например $Data::Dumper::Deparse (внизу связанного список), для распечатки подводных лодок.

А если вы не хотите распечатывать вещи, просто закомментируйте оператор use. Тогда они просто комментарии.

Он также достаточно портативный. Я просто трансплантировал Text :: Balanced и Smart :: Comments с моего компьютера в AIX box и вуаля. Готово.

1 голос
/ 23 января 2010

См. Как я могу использовать переменную в качестве имени переменной? для точки зрения использования переменных в качестве имен переменных. В противном случае вы должны использовать ссылки, предложенные Джоном и Полом Томблином.

1 голос
/ 23 января 2010

Передайте список имен переменных, а затем распечатайте их с помощью

foreach $varname (@list)
{
   print "$varname = $$varname\';
}

На самом деле, если подумать, это тоже не сработает, потому что $$ не сработает, потому что переменная не будет известна подпрограмме. Я не думаю, что вы сможете делать то, что вы хотите, за исключением помещения всех имен и значений переменных в хеш и их выгрузки с помощью Data :: Dumper. Обычно в этот момент я удаляю этот ответ, но некоторые другие ссылались на него, поэтому я не буду.

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

будет производить что-то вроде:

$VAR1 = {
          'a' => 'foo',
          'cVar' => 'this is cVar'
        };
1 голос
/ 23 января 2010

вы можете передать имя переменной в виде скаляра, а затем использовать ссылку для вывода значения. От 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
0 голосов
/ 24 января 2010

Для примера вот пример реального решения, предложенного несколькими вы используете 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';
0 голосов
/ 23 января 2010
# 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...