2016-07-24 31 views
9

Orada Perl hakkında "bilmek" birkaç şey vardır:Neden scalar sub {(@x, @y)} ->() scalar @y döndürüyor?

  • listeleri
  • fonksiyonları almak düzleştirmek ve dönüş listeleri

Bunu alabilir Yani eğer:

sub my_test { 
    my @x = qw(a b c); 
    my @y = qw(x y z t); 
    return (@x, @y); 
} 

say my_test; # a b c x y z t 
say scalar my_test; 

I İki sonuç değerinden birini bekliyoruz:

  • 7, çünkü bu öğe qw(a b c x y z t) listesinde kaç öğe var. Gerçekten de bu, scalar sub { @{[ qw(a b c x y z t) ]} }->()'dan aldığım şey. virgül operatörüyle (nefes) olarak virgül yorumlamak eğer ('a', 'b', 'c', 'x', 'y', 'z', 't') olsun, çünkü
  • 't'
  • , 't' olarak değerlendirilirse hangi. Aslında, scalar sub { qw(a b c x y z t) }->()'dan aldığım şey bu.

Bunun yerine ne alabilirim & hellip olduğu; 4, uyarı olmadan. Neden bir liste yassılaştırma ve virgül operatörü karışımı aldım?

sağlamalarının ve bu oldukça popüler desenli

Benzer hikayesi:

scalar default_override_hash üç karmaları döndü biliyoruz ve olması gerektiği değil sadece %overrides (ve her şeyi değil, '') elde eder nasıl
sub default_override_hash { 
    my %defaults = (foo => 'bar', egg => 'quuz'); 
    my %values = @_; 
    my %overrides = (__baz => ''); 
    return (%defaults, %values, %overrides); 
} 

scalar default_override_hash; # '1/8' 

ama skaler temsili bir karma olarak mı?

+0

Ben bekliyoruz tahmin 'scalar' alt my_scalar {benim @input = @_' gibi olmak; skallar @scalar; } ' – badp

+0

İlgili: http://stackoverflow.com/q/8232951/133939 – Zaid

cevap

7

En önemli nokta: Listeler düzleşmiyor. (Listeler düzdür, ancak düzleşmezler, çünkü bunu yapmak için ilk önce iç içe olmaları gerekir.)

, (comma işleci), liste bağlamında liste birleştirmesidir. Liste bağlamında A , B, bağlam içinde A ve B değerlendirir, sonra sonuçları birleştirir. skaler bağlamda

A , B C (veya JavaScript) gibi çalışır: Bu skaler bağlamda, sonra boşluk bağlamda değerlendirir (ve getiri) BA değerlendirir. (Boşluk bağlamda A , B aynı şekilde çalışır, ama çok boşluk bağlamda B değerlendirir.) return X yılında

, X bağlamı kendisini aramak fonksiyonunun bağlamıdır. Böylece sub my_test { return X } scalar my_test, scalar X gibidir. return, mevcut alt aramanın bulunduğu içeriğe dinamik olarak bakar ve işlenen ifadesini buna göre değerlendirir.

perldoc perlsub says A return ifadesi bağlamında bağlı olarak, isteğe bağlı olarak uygun bir bağlamda değerlendirilecektir döndürülen değeri belirleme, bir alt yordam çıkmak için kullanılan (liste, skaler veya boş) olabilir

altprogram görüşmesi.Yukarıda tarif edildiği gibi)

, skaler bağlamda @x, @y ardından değerlendirir ve skalar bağlamda @y döner) bir dizi için hiçbir şey yapmaz void bağlamda (@x değerlendirir. Skaler bağlamdaki bir dizi içerdiği öğe sayısını verir.

aynı mantık %defaults, %values, %overrides için de geçerlidir. , is left-associative, bu nedenle (%defaults , %values) , %overrides olarak ayrılır. Bu, %defaults , %values değerini void bağlamında değerlendirir (bu da %defaults, sonrageçersizdir, hiçbir etkisi yoktur), sonra değerlendirir ve skaler bağlamda %overrides döndürür. Skaler bağlamdaki bir karma, hash internals tanımlayan bir (yerine işe yaramaz) dize döndürür.

+0

kalın cümle yanlıştır. 'dönüş', içeriğe hiç bakmıyor. Olsa bile, 'dönüş', virgül operatöründen * sonra değerlendirilir, bu nedenle çalışma zamanında ne yapılacağı, virgül operatörüne herhangi bir etkide bulunamaz. Bu demek ki, 'iade', arayanın bağlamını (ya da yaptığı gibi) kontrol eden şeydir. Bunu yapan virgül operatörü. – ikegami

+0

doğru ifade olacaktır: ** virgül operatörü ('') dinamik olarak mevcut alt denilen bağlam bakar ve buna uygun olarak, işlenen bir ifade değerlendirir ** – ikegami

+1

@ikegami 'dönüş @ z' bir virgül sahiptir. ama hala geçerli alt bağlamında 'z' değerlendirir. – Oktalist

İlgili konular