2009-09-02 19 views
9

Bu en iyi uygulama sorusu.Uzay gemisi operatörü ne zaman kullanılır?

Sadece sayısal sıralama yordamlarında kullanılan Perl uzay gemisi operatörünü (< =>) gördüm. Ancak diğer durumlarda faydalı görünüyor. Pratik bir kullanım düşünemiyorum.

Herkes Perl türünün dışında kullanabileceğine dair bir örnek verebilir mi? Herhangi bir karşılaştırma yönteminde

+0

@ether: Yalnızca "operatör" etiketi? Yeni operatör etiketleri oluşturmayı sevdiğini düşündüm! –

cevap

7

Robot robotu Mary'ye gitmek ve onu yeniden şarj etmek isteyen robot için bir kontrol sistemi yazıyorum. Çizgi üzerindeki tamsayı noktaları boyunca hareket ederler. Joe, $ j'den başlar ve zaman birimi başına herhangi bir yönde 1 metre yürüyebilir. Mary hala $ m duruyor ve hareket edemiyor - iyi bir yeniden şarj ihtiyacı var! kontrol programı o şekilde görünecektir:

while ($m != $j) { 
    $j += ($m <=> $j); 
} 
2

. Örneğin karmaşık bir nesneye sahip olabilirsiniz ancak yine de tanımlanmış bir "sipariş" e sahip olabilirsiniz, bu yüzden bunun için bir karşılaştırma işlevi tanımlayabilirsiniz (, bir sıralama yönteminde kullanmak için kullanmanız gerekir),

package Foo; 

# ... other stuff... 

# Note: this is a class function, not a method 
sub cmp 
{ 
    my $object1 = shift; 
    my $object2 = shift; 

    my $compare1 = sprintf("%04d%04d%04d", $object1->{field1}, $object1->{field2}, $object1->{field3}); 
    my $compare2 = sprintf("%04d%04d%04d", $object2->{field1}, $object2->{field2}, $object2->{field3}); 
    return $compare1 <=> $compare2; 
} 

Bu, tamamen mahrum edilmiş bir örnektir. Ancak, şirketimdeki kaynak kodunda, tarih ve saat bilgilerini tutmak için kullanılan nesneleri karşılaştırmak için neredeyse tam olarak yukarıdakileri buldum.

Ben istatistiksel analiz için aklınıza gelebilecek bir diğer kullanım - değeri kümesinin aritmetik orta değerinden daha yüksek veya daha düşük olması durumunda bir değer defalarca değerler listesine göre çalıştırılırsa, görebiliyorsun:

use List::Util qw(sum); 
# $result will be 
# -1 if value is lower than the median of @setOfValues, 
# 1 if value is higher than the median of @setOfValues, 
# 0 if value is equal to the median 
my $result = sum(map { $value <=> $_ } @setOfValues); 

wikipedia'dan bir tane daha: "İki argüman karşılaştırılamazsa (örneğin, biri NaN'dir), operatör undef değerini döndürür." Yani, daha az şifreli olan Scalar::Util :: looks_like_number için kişisel olarak ben gideceksem, iki sayının aynı anda bir sayı olup olmadığını belirleyebilirsiniz.

+2

Aslında, 'undef' davranışı sorunlara neden olabilir, çünkü 'undef' bir şekilde Perl'in büyük olasılıkla ölmesine neden olur. Ancak, NaN'nin: alt sayısal {$ a <=> $ b // ($ a == $ a) - ($ b == $ b)} işleyen bir sayısal sıralama yapabiliriz. En azından ölmemenin olumlu etkisi vardır. –

5

<=> operatörü binary search algorithm için faydalı olacaktır. Çoğu programlama dilinin, üç yollu bir karşılaştırma yapan bir operatörü yoktur; bu, yineleme başına iki karşılaştırmanın yapılmasını gerektirir. <=> ile sadece bir tane yapabilirsiniz.

sub binary_search { 
    my $value = shift; 
    my $array = shift; 
    my $low = 0; 
    my $high = $#$array; 

    while ($low <= $high) { 
     my $mid = $low + int(($high - $low)/2); 

     given ($array->[$mid] <=> $value) { 
      when (-1) { $low = $mid + 1 } 
      when (1) { $high = $mid - 1 } 
      when (0) { return $mid  } 
     } 
    } 

    return; 
} 
+0

Şaşırtıcı derecede zor bir şekilde, bir ikili aramanın * doğru bir şekilde uygulanması gerektiğine bakılırsa, sadece dünyaya başka bir kırık örnek vermediğimi umuyor olabilirim. : P –

+0

Bu iki karşılaştırmayı açık yazılı ifadelerden önişlemcinin dahili içeriğine devretmenin performans yararı nedir? –

+1

Bayt kodu düzeyinde bir operatör var, iki değil: 'perl -MO = Terse -e" $ a <=> $ b "' Bu, Perl C içinde uygulandığı için (üç yönlü bir karşılaştırma operatörü olmayan) "<=>", dahili kullanıcılar tarafından iki karşılaştırma olarak uygulanmalıdır. Herhangi bir performans avantajı, genişlemenin Perl yerine C ile gerçekleşmesidir. Elbette, en nihayetinde, sınır, işlemcinin komut setinin, hangi operatörlerin C'ye sahip olduğuna bakılmaksızın desteklediği şeydir. –

İlgili konular