2

ハッシュの一部をサブルーチンに渡すにはどうすればよいですか?

%list = ( 1 => {name => 'first', quantity => 2},
  2 => {name => 'second', quantity => 3});
$i = 2;

#doesn't work....
check_something ( \%{list}{$i} );
sub check_something {
   %local = @_;
}

#doesn't work....
check_something ( \%list, $i );
sub check_something {
   my ($ref, $item) = @_
   %local = %{$ref}{$item};
}
4

3 に答える 3

1

サブルーチンに渡し$list{$i}

use strict;

check_something ( $list{$i} );

sub check_something {
   my ($href) = @_;

   # $href->{name}, $href->{quantity}

   my %hash = %$href;
   # $hash{name}, $hash{quantity}
}
于 2013-06-10T20:05:27.003 に答える
1

これは機能します:

use strict;
use warnings;


my %list = ( 
    1 => {name => 'first', quantity => 2},
    2 => {name => 'second', quantity => 3}
);
my $i = 2;

check_something ( $list{$i} );

sub check_something {
   my $item = shift;
   #...
}
于 2013-06-10T20:05:54.487 に答える
0

スカラー データ以外のものを Perl 変数に格納するときはいつでも、オブジェクト指向の Perl について考え始める必要があります。

Perl Object Oriented Tutorialを見てください。

私はあなたのここですべてのオブジェクト指向に行きます:

#! /usr/bin/env perl

use strict;
use warnings;

my %list;

my $list{1} = Widget->new("first", 2);
my $list{2} = Widget->new("second", 3);
my $i = "2";
check_something( $list{$i} );

わお!私が何をしているのかは明らかです。%listウィジェットのオブジェクトを含むハッシュが呼び出されました! サブルーチンcheck_somthingが Widget オブジェクトを取得しています。$list{$i}それは引数としてあるはずです。

しかし、ウィジェットはどのように見えますか:

package Widget;
sub new {
    my $class    = shift;
    my $self     = shift;
    my $name     = shift;
    my $quantity = shift;

    my $self = {};
    bless $self, $class;
    $self->Name($name) if defined $name;
    $self->Quantity($quantity) if defined $quantity;
    return $self;
}

sub name {
    my $self = shift;
    my $name = shift;

    if ( defined $name ) {
       $self->{name} = $name;
    }
    return $self->{name};
}

sub Quantity {
    my $self    = shift;
    my $quanity = shift;

    if ( defined $quanity ) {
       $self->{quantity} = $quantity;
    }
    return $self->{quantity};
}

それはとても簡単です。ハッシュのハッシュの代わりにオブジェクトを使用することで、ロジックを簡素化しました。サブルーチンに渡したいものが Widget オブジェクトであることは簡単にわかります。実際、check_somthingサブルーチンは別のメソッドである可能性があります。

sub check_something {
    my $widget = shift;

    my $name = $widget->Name;
    my $quanity = $widget->Quantity;

    # Here be dragons...

    return ???
}

今、私のコードは次のようになります。

#! /usr/bin/env perl

use strict;
use warnings;

my %list;

my $list{1} = Widget->new("first", 2);
my $list{2} = Widget->new("second", 3);
my $i = "2";

$list{$i}->check_something;

これにより、コードを改善する多くのことが行われることに注意してください。

  • まず、ロジックをクリーンアップします。リストのハッシュやハッシュ、または理解するのが難しい構造を渡しているわけではありません。おそらく、あきらめてここで質問する前に、理解するのに2〜3時間無駄にしました。(犯罪はありません。私はそこに行って、自分でやったことがあります)。代わりに、理解しやすいオブジェクトを渡しています。
  • 次に、check_somethingサブルーチンがウィジェットでのみ使用できるようにします。Widget 以外のオブジェクトを に渡そうとするcheck_somethingと、失敗します。さらに良いことに、別のオブジェクトWoobleを独自のcheck_somethingサブルーチンで呼び出すことができ、Perl は私が実際に何をチェックしているかを判断します。

例えば:

my $widget = Widget->new("first", 2);
my $wooble = Wooble->new(1, "slam");

$widget->check_something;
$wooble->check_something;

Widgets と Woobles には独自のcheck_somethingメソッドがあり、Perl は、どのオブジェクトがWidgetで、どのオブジェクトがWoobleであるかを認識しているため、実行する必要があるものを認識していcheck_somethingます。

  • 最後に、use strict;もう壊れていません。プラグマはエラーのuse strict;90% をキャッチします。ただし、これらの複雑な構造を未加工のコードから切り出して作成すると、キャッチできてuse strict;もキャッチできない同じ時間のエラーが発生する可能性があります。

例えば:

%list = (
    1 => {name => 'first', quantity => 2},
    2 => {name => 'second', quanity => 3}
);

エラーが表示されますか? 私は一方を使用quantityしましたが、もう一方はスペルquanityを間違えました。このタイプのエラーは、コンパイラによってキャッチされません。でも:

$list{1} = Widget->new;
$list{1}->name('first');
$list{1}->quantity(2);

$list{2} = Widget->new;
$list{2}->name('second');
$list{2}->quanity(3);    #Compiler Error!

これで、Perl コンパイラは私のエラーをキャッチします。これquanityは、単にハッシュ参照へのキーではなく、存在しないサブルーチンであるためです。

他の人はすでに技術的に正しい答えを与えていますが、ハッシュのハッシュ、リストのハッシュ、またはハッシュのリストなどの複雑なデータ構造を定期的に使用する場合は、オブジェクトの操作を開始するときが来ました。それらに慣れると、フラストレーションやロジックの問題が少なくなり、はるかに高速にコーディングできることがわかります。

于 2013-06-11T03:25:18.333 に答える