5

未定義とゼロの両方が有効な結果である検索ルーチンを作成しています。($result, $answer)「未定義だが真」の値がないため、のように2要素の配列を返します。それはうまく動作しますが、少し厄介です。クラスはやり過ぎのようです。

そのようなものは存在しますか、それとも何らかの形で偽造することができますか?0E0トリックなどを考えています。

詳細。これが私が望むユーザーインターフェースです。現在のルーチンは、結果(キーが見つかったかどうかに関係なく)と、見つかった場合は値の2つの値を返します。

my $result = search_struct($key, $complex_data_structure);
if ($result) {
    print "A result was found for $key!  Value is: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}
4

4 に答える 4

8

結果への参照を返すことができます。undef結果がない場合、\( undef )文字通りの未定義の結果の場合\( whatever )、その他の結果の場合は戻ります。次に、呼び出し元は(定義され$$resultていることを確認した後)使用できます。$result

于 2012-10-08T14:25:16.897 に答える
5

いいえ。ただし、3つの状態を返す方法は多数あります。

解決策1

  • 空のリスト(return;
  • 未定義(return undef;
  • 文字列(return "foo";

my $found = my ($result) = search_struct($key, $data);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

スカラーコンテキストでのリストの割り当ては、右側から返される要素の数に基づいて評価されます。

解決策2

  • False(return undef;
  • 未定義への参照(return \undef;
  • 文字列への参照(return \"foo";

my $result = search_struct($key, $data);
if ($result) {
    print "$key: ", $$result // "Undefined!", "\n";  # Note change here!
}
else {
    print "Sorry, no result was found for $key.\n";
}

解決策3

  • False(return 0;
  • True、およびundef(return (1, undef);
  • True、および文字列(return (1, "foo");

my ($found, $result) = search_struct($key, $data);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

解決策4

  • False(return 0;
  • True、undefがパラメータとして返されます($_[2] = undef; return 1;
  • True、文字列がパラメータとして返されます($_[2] = "foo"; return 1;

my $found = search_struct($key, $data, my $result);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

ところで、最初のパラメーターとしてデータ構造を渡し、2番目のパラメーターとしてキーを渡します。オブジェクト指向プログラミングのようなものです。

于 2012-10-08T16:33:01.553 に答える
2

答えを(配列ではなく)リストで返す場合があります。結果が見つからない場合は空のリスト、それ以外の場合は1つの要素のリスト((undef,)または($some_answer,))。

それはまだかなり不格好ですが、:

if (my ($answer) = the_function()) { # note parentheses
  process_answer($answer);  # might be undef, false, etc.
} else {
  no_results_found();
}
于 2012-10-08T15:41:34.877 に答える
0

「未定義」も「真」になるにはどうすればよいでしょうか。なぜあなたはそのような構造が欲しいのですか?関数が入力で定義されていないことを返すためには、そのような結果も「真」であってはならないことに気づいていませんか。

ただし、Perl 5.10以降、述語not-a-defined-falseは次のとおりです。

if ( possibly_undefined() // 1 ) { 
}

しかし、実際には、ゼロが真である方が検索関数に適していると思います。

my ( $value ) 
    = map  { $repos->get( $_ ) } 
      grep { $_ } 
      $repos->find( $lookup_criteria )
    ;

関数のブール値は、find「見つけましたか?」という質問を表します。インデックスは、「どのインデックスで?」という質問を表します。インデックスが見つからない場合は、''またはを返しundefます。Zero-but-trueは、「最初のインデックスで見つけた」という意味です。

ただし、必要なブール値と整数の解釈を使用して、いつでもクラスを作成できます。以下のクラスは、整数コンテキストでは整数として定義でき、数値が奇数かどうかをテストするときにfalseとして定義できるオブジェクトを定義します。

package Odd; 
use strict;
use warnings;
use overload qw<bool boolean_result 0+ value fallback 1>;
sub new { return bless do { \( my $v = $_[1] ) }, $_[0]; }
sub boolean_result { return ${ $_[0] } % 2; }
sub value          { return ${ $_[0] }; }
sub set_value      { ${ $_[0] } = $_[1]; return $_[0]; }

package main;
use strict;
use warnings;
use Test::More;
my $odd = Odd->new( 1 );
is( $odd + 0, 1 );
is( !$odd, '' );
is( !!$odd, 1 );
my $even = Odd->new( 2 );
is( $even + 0, 2 );
is( !$even, 1 );
is( !!$even, '' );
done_testing();
于 2012-10-08T15:03:10.450 に答える