-1

こんにちは、2 つの数値を比較して、一方が他方よりも大きいか小さいかを確認する単純なサブルーチンを作成しようとしています。これまでのところ、次のコードがあります。

sub Value
{  my $num = $_[0];

   my ($last) = shift;

  my $compare = sub {    
 if ($last < $last) {print "Less than \n"; } else {print "Greater than \n";};};

 my $hashtable; 
 $hashtable->{"compare"} = $compare;
 $hashtable; }


#Execute Statement
my $num1 = Value(57.8);
my $num2 = Value(129.6);

print  "Check: ",  $num1->{"compare"}->($num2);

これを正しく機能させる方法について誰か提案がありますか? ありがとう!

4

2 に答える 2

3
  1. で展開する引数を台無しにしましたValues。最初の引数をに割り当て、$num次にshift最初の引数をに割り当てます。$lastしたがって$num、と$lastは常に同じ値になります。
  2. と比較$lastしますが$last、これは役に立ちません。
  3. クロージャーをに入れますが、フィールド$hashtable->{compare}の内容である。を実行します。checkundef
  4. クロージャは、現在選択されているファイルハンドルにデータを出力しますが、有用な情報は返しません。戻り値を出力するのは賢明ではないようです。
  5. $num1$num2はクロージャであり、数値ではありません。クロージャは引数をアンパックしないため、クロージャに引数を渡しても何も起こりません。

問題に対処する必要がある実装は次のとおりです。

use strict; use warnings;
use Test::More;

sub create_closure {
  my ($x) = @_;
  my $operations = {
    compare => sub { my ($y) = @_; return $x <=> $y },
    add     => sub { my ($y) = @_; return $x  +  $y },
    value   => $x,
  };
  return $operations;
}

# some tests
my $ops = create_closure(15);
ok( $ops->{compare}->(15) ==  0, "compare to self" );
ok( $ops->{compare}->(20) <   0, "compare to larger");
ok( $ops->{add}->(5)      == 20, "add");
ok( $ops->{value}         == 15, "value");

my $ops1 = create_closure(150);
ok( $ops1->{compare}->($ops->{value}) > 0, "compare to smaller value");

done_testing;

編集

2つを直接比較することはできません$opsが、元の値を返すフィールドを作成することはできます。

ただし、そのようなことをより頻繁に行う場合は、オブジェクトと演算子のオーバーロードを使用することをお勧めします。

use strict; use warnings; use Test::More;

{
  package Ops;
  sub new {
    my ($class, $val) = @_;
    if (ref $val eq __PACKAGE__) {
      ($val, $class) = ($$val, __PACKAGE__);
    }
    bless \$val => $class;
  }
  use overload
    # overload numeric coercion
    '0+' => sub { ${ $_[0] } },
    # overload addition. Take care to dereference to avoid infinite loops.
    '+'  => sub {
      my ($self, $other) = @_;
      Ops->new($$self + $other);
    },
    # overload numeric comparision. Take care to swap the args if neccessary.
    '<=>' => sub {
      my ($self, $other, $swapped) = @_;
      (my $val, $other) = $swapped ? ($other, $$self) : ($$self, $other);
      Ops->new($val <=> $other);
    }
}

my $ops1 = Ops->new( 15);
my $ops2 = Ops->new(150);

# some tests
ok( ($ops1 <=> 15)   ==  0, "compare to self" );
ok( ($ops1 <=> 20)   <   0, "compare to larger");
ok( ($ops1  + (5))   == 20, "add");
ok(  $ops1           == 15, "value");
ok( ($ops2 <=> $ops1) >  0, "compare to smaller value");

done_testing;
于 2013-03-23T18:53:43.913 に答える
1

次のようにします。

 our $last;

 sub compare
 {
    my ($x, $y) = @_;
    if( $x > $y )
    {
       print("$x is greater than $y\n");
    }
    elsif( $x == $y )
    {
       print("$x is equal to $y\n");
    }
    else
    {
       print("$x is less than $y\n");
    }

    $last = ($x, $y);
 };
 my $lastValues = compare(3, 4); # pass numbers which you want to compare instead of 3 and 4

 print("last compared value = $lastValues");
于 2013-03-23T17:47:45.773 に答える