2017-05-29 3 views
0

私は自分のカスタムを書こうとしています。validateParameter perlの関数です。 私も作品次のコードを持って実際:関数のパラメータがperlの文字列であるかどうかをチェックする方法

sub validateParameter { 
    my ($args, $list) = @_; 

    if (ref($list) eq "ARRAY") { 

     foreach my $key (@$list) { 
      if (not defined $args->{$key}) { 
       die "no $key given!"; 
      } 
     } 
    } 
    #elsif (check if string) { 
    #} 
} 

を私は次のように私の関数を呼び出すようにしたい:

validateParameter({ hallo => "Welt", test => "Blup"}, ["hallo", "test"]); 

が、私はまた、このように私の関数を呼び出すしたい:

validateParameter({ hallo => "Welt", test => "Blup"}, "hallo"); 

指定されたargが "文字列"かどうかを確認するにはどうすればよいですか?

私は、perlには次の3つのデータ型(スカラー、ハッシュ、配列)しか持たないことが分かります。しかし、変数が文字列かどうかを調べるスマートな方法があるかもしれません。

皆様に感謝します。

+0

"数字"ではなく "文字列"を意味しますか?または "arrayref/hashref/..."とは対照的に "string"ですか?その後、['ref'](http://perldoc.perl.org/functions/ref.html)が(あなたがすでに行ったように)行く方法です。単純な非refスカラー( '$ list'のような)のための空文字列を返します。 – PerlDuck

+0

Ohh okay私のせいだ。この投稿は完了です。ありがとう@PerlDuck –

答えて

1

いいえ、コンテキストによってはPerlが暗黙の型変換を行うため、スカラーが文字列かどうかを確認する方法はありません。関数に2番目の引数として数値を与え、文字列を必要とするコンテキストで使用すると、自動的に文字列に変換されます。ですから、ref($ list)が空であるかどうかを確認してください。そのような場合、$ listは参照ではないので、文字列か数字であり、これらの2つを区別する必要はありません。

+1

番号を検出するには[Scalar :: Util :: looks_like_number](http://perldoc.perl.org/Scalar/Util.html#looks_like_number)(コアモジュール)がありますが、私は思っていませんそれはOPが後になったものです。 – PerlDuck

+0

'ref($ list)'は、文字列の過負荷が発生したオブジェクトに対してtrueを返すことに注意してください。これは 'my $ url = URI-> new( 'http://stackoverflow.com/')という意味です。 '$ url'を文字列として使うことができても、' ref 'を使うとvalidateParameter({hallo =>" Welt "、test =>" Blup "}、$ url);'は失敗します。 – ikegami

3

更新:私は何とか質問の終わりを逃した。あなただけのパラメータを逆参照しようとする必要があり、ちょうどref($list) eq 'ARRAY'をテストすることはほとんどの時間を動作しますが、適切にでもオーバーロードされたオブジェクトを許可する:

if (eval { \@$list }) { 
    # it was an array 
} 
else { 
    # assume it is a string 
} 

オリジナルの答え:

あなたは、パラメータについて多くのことを確認することができます:

if (! defined $param) { 
    # undefined 
} 
elsif (defined Scalar::Util::blessed($param)) { 
    # object 
} 
elsif (ref $param) { 
    # reference (return of ref will give the type) 
} 
elsif (length do { no warnings "numeric"; $param & '' }) { 
    # number 
} 
else { 
    # string 
} 

しかし、(おそらく定義されたチェックを除く)すべてのことは、一種のの目的に反しPerlの自動ご希望のタイプに変換し(例えば、文字列またはdualvar渡すことができるものを制限することになるNU文字列、数値、または参照が必要なオーバーロードされたオブジェクト、または束縛された変数または$!などの魔法の変数)が必要です。

また、Params::Validateの機能を見ることもできます。

+0

注: '\ @ $ list'は、' $ list'が 'undef'ならばそれを自動的に動かしますので、' undef'を最初に処理してください。 – ikegami

+0

@ikegami私は、undefがundef "string"よりも空の配列に似ていると推測していました。 – ysth

1

実際にはこのようなことはないので、引数の "タイプ"に基づいて動作させないでください。 Perlの値に複数の型があることが多いため、型ベースの多型を使用すると問題に遭遇します。

例えば、"123"によって生成

  • スカラーは、文字列としてとして格納されるが、Perlは文字列として格納されていない123によって生成スカラーからそれを区別しません。

  • スカラーには、その番号の数とキャッシュされた文字列の両方を含めることができます。 (例:my $i = 123; "".$i;

  • スカラーには、数値と文字列の両方を含めることができます(数値の文字列化ではありません)。これらの一般的な例は、$!!1です。

  • 文字列をオーバーロードするオブジェクトへの参照も有用な文字列です。 (例えば、DateTime->now

  • アレイへの参照は、ハッシュリファレンスとして使用できるように、%{}をオーバーロードする可能性があります。ハッシュへの参照は、@{}を配列参照として使用できるようにオーバーロードする可能性があります。

  • 以上。

関連する問題