1

変数が文字列または数値として渡されることを期待している状況があります。

すなわち

sub foo {
    # These can be either strings or numbers
    my ($bar, $var, $star) = @_;

    # I need to check to see if $bar is the number 0 (zero)
    if ($bar == 0) {
        # Do super magic with it
    }
}

残念ながら、Perl は、文字列が含まれている場合にスーパー マジックを実行しようとし$barます。

数値が0 (ゼロ)$barの場合に限り、スーパー マジックを実行するように Perl に指示するにはどうすればよいですか?

Perl は基本的にコンテキストに基づいて解釈することを理解しています。これがここでの根本的な問題です。この問題の可能な解決策は正規表現を使用することですが、これは問題ありませんが、別の「簡単な」解決策があるかどうかを知りたかったのです。

前もって感謝します。

4

4 に答える 4

4

私は個人的に@Disco3のコメントが言ったことに行きます。

if ($bar eq 0) { ... }

これは で機能し、$bar = 0期待される結果が得られます。$bar = 'foo'$bar = 123

ただし、ここに興味深い事実があります。

use Benchmark qw(cmpthese);
my $bar = '0';

cmpthese(-1, {
  'quoted'    => sub { $bar eq '0'    },
  'unquoted'  => sub { $bar eq 0      },
  'regex'     => sub { $bar =~ m/^0$/ },
});

これら 3 つのソリューションをベンチマークすると、引用されていないソリューションが0最速の方法であることがわかります。

               Rate    regex   quoted unquoted
regex     4504851/s       --     -70%     -76%
quoted   15199885/s     237%       --     -19%
unquoted 18828298/s     318%      24%       --
于 2012-07-09T15:18:22.490 に答える
2

「0番」が何を意味するかによります。明らかに、1 つの文字列0はゼロです。しかし、3 つの文字列についてはどうでしょ0.0うか。

1 つの文字列と一致させたい場合は、次0を使用します。

if ($bar eq '0') {
   ...
}

Perl がゼロと見なすものと一致させたい場合は、次を使用します。

use Scalar::Util qw( looks_like_number );

if (looks_like_number($bar) && $bar == 0) {
   ...
}
于 2012-07-09T16:06:37.677 に答える
2

なぜだめですか:

if ( $bar =~ m/^0$/ ) {
于 2012-07-09T15:08:59.407 に答える
0

looks_like_numberと数値を比較すると、非常に簡単に非常に良い結果が得られます。

use Scalar::Util qw(looks_like_number);
use Test::More tests => 7;

sub is_numerically_zero {
    my ($string) = @_;

    return (looks_like_number($string) and $string == 0);
}

for my $string (qw(0 0.0 0e0), '  0  ') {
    ok(is_numerically_zero($string));
}

for my $string (qw(duckies 123), '') {
    ok(not is_numerically_zero($string));
}

これは、リテラル string だけに一致させたくないことを前提としています'0'

于 2012-07-09T18:25:29.100 に答える