2011-10-09 18 views
5

Ruby'nin temellerini öğreniyorum (sadece başlangıç) ve Hash.[] method ile karşılaştım. Biraz düşünceyleRuby sözdizimsel şeker için "kurallar" var mı?

a = ["foo", 1, "bar", 2] 
=> ["foo", 1, "bar", 2] 
Hash[*a] 
=> {"foo"=>1, "bar"=>2} 

ile tanıtıldı, ben Hash[*a]Hash.[](*a) veya Hash.[] *a denk olduğunu anladım. Benim sorum bu yüzden durum buydu. Bu, *a'u köşeli parantez içine koymanıza izin verir ve "o" ifadesinin nerede ve ne zaman kullanılabileceği konusunda bir kural var mı?

Düzenleme: Benim ifadeler bazı karışıklıklara neden olmak gibi görünüyor. Dizi genişlemesini sormuyorum. Anladım. Sorum şu: Temel olarak [] bir yöntem ismidir, neden argümanları parantez içine koymak sorun olur? ama tamamen değil - - Neredeyse görünüyor Eğer bir yöntem Foo.dood varsa ve buna dize "hey" geçmek istediğini söyleyerek gibi, o zaman Foo.do"hey"od yazabiliriz.

+0

Bir yöntem çağırma işleminde * a'ya odaklanan birçok yanıt görüyorum. Ancak, [1, * a] 'nın neden beklendiği gibi çalıştığı ([1, a]' dan farklı bir sonuç veren) ve neden [* a,] gibi diğer prodüksiyonları da görmek güzel olurdu. 1] geçersiz. Ayrıca "uyarının" ödevle nasıl bağlantılı olduğunu ve Ruby'nin ödev-dekompozisyonu ile nasıl etkileşime gireceğini/nasıl etkileşime girdiğini görmek de hoş olurdu ... belki de belki de tamamen farklı bir SO sorusu ;-) Olsaydı * gerçekten güzel olurdu * yarı resmi yakut belirtimi. Yarı spesifikasyonlara bağlantılar, cevapları daha iyi hale getirecektir. –

+0

@pst: iyi sorular. Bu konuda yeni bir soru sorarsanız, bağlantıyı buradan takip edebilirim. –

+0

her zamanki yolun bir çiftler dizisi göndererek kullandığını unutmayın: Hash [[[anahtar1, değer1], [anahtar2, değer2]]] – tokland

cevap

3

yakut özel bir aramak olanak veren bir çift yöntemleri vardır olurdu

Hash[*a] benzer yol. Bunlar da belirtildiği gibi [], +, -, == ve başka sözü biri olarak gibidir.Bir başka önemli örnek, object.something = value ile çağrılabilecek ve erişim oluşturmanıza izin veren something=(value) formunun yöntemleridir.

Düzenleme:

İşin eğlenceli yanı 1: Bir + yöntemi tanımlarsanız ücretsiz += olsun.

İşin eğlenceli yanı 2: Bir <=> tanımlamak eğer ben Ruby'nin sözdizimi YARV Ruby için parse.y tanımlanır düşünüyorum tüm karşılaştırma yöntemlerini, Comparable

+0

Bu "özel" şeylerin bir yerinde bir liste var mı? –

+1

IMHO'nun gereksiz yere indirilmemesi için burada [http://www.zenspider.com/Languages/Ruby/QuickRef.html#28] –

4

Hash["a", "b", "c", "d"]Hash.[]("a", "b", "c", "d") eşdeğerdir. Ruby'deki neredeyse her şey bir yöntem çağrısıdır. 5 + 5, 5.+(5)'a eşdeğerdir. Verilen a = ["a", "b", "c", "d"]Hash[*a]

sırayla Hash.[]("a", "b", "c", "d") eşdeğerdir Hash["a", "b", "c", "d"], eşdeğerdir. Benzer şekilde, foo(*a)foo("a", "b", "c", "d") Bu operatör patlayabilir denir eşdeğerdir ve bir yönteme, bir dizi gönderme ve dizideki her öğe yöntemine bir bağımsız değişken olarak sayısına sahip, yerine ilk bağımsız değişken olarak yönteme dizi gönderme sağlar.


özel olarak parantez içine *a koymak sağlayan özel bir şey yok, Güncellemenizle cevaplamak için. Köşeli parantez normal bir yöntem çağrısı için şekerdir. Buradaki tek "özel" şey, herhangi bir yönteme *a gönderebilmenizdir.

+0

Peki, yayılma genişlemesinin izin verildiği yerler nelerdir? (AFAIK yöntemine başvurmayla ilgili olmayan en az bir tane daha var.) –

+0

Güncelleme? Hiçbir şey güncellemedim. Yani bu köşeli parantezin Ruby'de bir yöntem adı olarak her yerde gerçekleştiğini, argüman listesini içermek için parantez yerine parantezleri kullanabileceğinizi mi söylüyorsunuz? I.e herhangi bir eski yöntem olan Foo. [] 'Argümanları a, b ve c olarak almak Foo [a, b, c]' olarak yazılabilir mi? Bu sadece sihirli bir dil özelliği mi? –

+0

Bu doğru. My_obj [foo] 'ile [] adlı bir yöntem çağrılabilir. [] = Adlı bir yöntem, my_obj [foo] = bar' ile çağrılabilir. Bu, my_obj. [] = (Foo, bar) 'a dönüşür. Bu, Hash'un örneklerinin sözdizimini güçlendirir. Ayrıca "Dir. [] (" Glob pattern ")' e dönüşen Dir ["glob pattern"] 'vardır. –

0

*<Array> yöntemi, diziyi dizi olarak değil, 'genişletilmiş' dizisini kullanmasını söyler.

Örnek: dizisi bir ve tek parametredir

def test(*argv) 
    p argv 
end 

a = [1,2,3] 
test(a) #-> [[1, 2, 3]] 
test(*a) #-> [1, 2, 3]  

test(a) ile. test(*a) bir ile

parametrelerin bir listesi olarak kullanılır. Senin durumunda


a = ["foo", 1, "bar", 2] 
Hash[*a] 

Hash[["foo", 1, "bar", 2]] 
+0

Doğru, ama bu nerede izin verilir veya izin verilmez? (ör. üretim kuralları nelerdir?) –

+0

Kullandığınız yönteme bağlı olarak. 'a' bir dizidir,' a' parametrelerin listesidir. Yani, soru değil, '' a' izinlidir, ancak: Bir diziye parametre olarak ihtiyacım var mı yoksa bir parametre listesine mi ihtiyacım var? – knut

+0

Sorumum dizi genişletme hakkında değil. Bu, [[] 'yöntemiyle ve özellikle de argümanların bu parantez içine yerleştirilmesinin neden sorun olduğu ile ilgilidir. –

2

nezaket olsun.

+0

+1 geçersiz kılınabilecek bir işleç listesi bulunmaktadır. –

İlgili konular