1

特定の引数をコンストラクター型に渡すさまざまな方法について、漠然と混乱しています。\%hashハッシュ参照またはリストのみを渡したいのですfoo => 1, bar => 1が、両方croakは渡したくありません( single elements, array reference )

たとえば、参照またはリストを渡します..(This works for the way I do this)

my $obj = foo->new;
my $data = $obj->dump( \%hash );
my $data = $obj->dump( foo => 1, bar => 1 );

また

my $obj = foo->dump( \%hash );
my $obj = foo->dump( foo => 1, bar => 1 );

パッケージ モジュール:

package foo;

use strict;
use Carp;

use Scalar::Util qw/reftype/;

sub new { return bless {}, shift }

sub dump {
   my $class = shift;
   my $self  = shift;
   unless ( reftype( $self ) eq reftype {} ) {
         croak("Constructor method not a hash type!");
   }
}

1;

ここで条件演算子を使うことも考えました? :が、うまくエラーにできません。

my $self  = reftype($_[0]) eq reftype {} ? shift : {@_};

これを行うためのより良い方法はありますか?

4

2 に答える 2

2

メソッドを呼び出すことができるさまざまな方法を見るdumpことができます。

「ハッシュリスト」を渡すと、要素の数は偶数 ( @_ % 2 == 0) になります。また、少なくとも 1 つのキーと値のペアが存在する場合、最初の引数 (キー) は文字列であるため、not defined reftype $_[0]保持されます。

ハッシュ参照を渡す場合、引数リストはこの参照のみを保持し、他の値は保持しないでください: @_ == 1. 最初の引数はハッシュになります: reftype($_[0]) eq 'HASH'.

したがって、引数をハッシュ参照に入れるには、次のようにすることができます。

sub dump {
  my $invocant = shift;
  my $hashref;
  if (@_ == 1 and reftype $_[0] eq 'HASH') {
    $hashref = $_[0];
  } elsif (@_ % 2 == 0 and (@_ == 0 or not defined reftype $_[0])) {
    $hashref = +{ @_ };
  } else {
    croak "Unknown argument format: either pass a hashref, or an even-valued list";
  }
  ...; # do something with $hashref
}

がクラス名なのかオブジェクトなのかを調べる$invocantには、それが bless されているかどうかを尋ねてください:

if (defined Scalar::Util::blessed $invocant) {
  say "Yep, it is an object";
} else {
  say "Nope, it is a package name";
}
于 2013-07-11T15:58:37.137 に答える
2

「ハッシュリスト」のようなものはありません。foo => 1, bar => 1、単なる 4 つの要素のリストです。ハッシュ参照と偶数の引数を受け入れたいようです。

sub dump {
   my $self = shift;
   my %args;
   if (@_ == 1) {
      croak("...") if (ref($_[0]) // '') ne 'HASH';
      %args = %{ $_[0] };
   } else {
      croak("...") if @_ % 2 != 0;
      %args = @_;
   }

   ...
}
于 2013-07-11T16:00:28.683 に答える