Ruby, nasıl baskı yapar() gerçekten işe?
Bir dersimiz var 10 ** ve aşağıdaki gibi point * 3 gerçekleştirme bildiği söyleniyor
class Point
def initialize(x,y)
@x, @y = x, y
end
def *(c)
Point.new(@x * c, @y * c)
end
end
point = Point.new(1,2)
p point
p point * 3
Çıkış:
#<Point:0x336094 @x=1, @y=2>
#<Point:0x335fa4 @x=3, @y=6>
ama daha sonra
3 * point
anlaşılan:
PointFixnum(TypeError) verileri geri kazanabilir mi
Başka bir örnek yöntemi coerce tanımlamak gerekir.
class Point
def coerce(something)
[self, something]
end
end
p 3 * point
Çıkış:
#<Point:0x3c45a88 @x=3, @y=6>
3 * point 3.*(point) ile aynı olduğunu söyledi. Bu, * bir argüman alır örnek yöntemi 24 ** ve nesnesi 3 çağırmak.
Şimdi, bu yöntem beri * bir nokta, yani çarpmayı bilmiyor
point.coerce(3)
adı verilecek ve geri bir dizi:
[point, 3]
ve sonra * bir kez daha uygulanmış, bu doğru mu?
Şimdi, bunu anladı ve şimdi Point sınıf örnek yöntemi * tarafından gerçekleştirilen Point yeni bir nesne var.
Soru:
point.coerce(3)kim çağırır? Ruby otomatik olarak mı, yoksa bazı kod içinde istisna yakalamaFixnum*yöntem mi? Ya da bilinen türlerinden biri bilmiyor, o zamancoercearamacaseBeyannamenin değil mi?coerceher zaman 2 öğeleri bir dizi dönmek gerekiyor mu? Hiçbir dizi olabilir mi? Ya bu 3 elemanları bir dizi olabilir?Ve, orijinal operatör (veya yöntem)
*sonra öğe üzerinde çağrılacak kural öğesi 1 argümanı ile 0,? (0 ve eleman elemanı 1 ise bu dizinin iki unsur*.* 40 tarafından döndürülür) Bunu kim yapar? Ruby tarafından yapılır veyaFixnumkod tarafından yapılır? EğerFixnumkod tarafından yapılırsa o zaman "Kongre" herkes bir zorlama yaparken izler?.Bu yüzden
Fixnum*kod olmak böyle bir şey yapıyor olabilir:class Fixnum def *(something) if (something.is_a? ...) else if ... # other type / class else if ... # other type / class else # it is not a type / class I know array = something.coerce(self) return array[0].*(array[1]) # or just return array[0] * array[1] end end endÇok zor bir şey
Fixnum47 ** örnek yöntem? eklemek için, Zaten içinde bir sürü kod var ve onu geliştirmek için birkaç satır (ama biz hiç olmak istersiniz?) ekleyebiliriz.Pointsınıfcoerceoldukça genel ve geçişli oldukları için*veyaile çalışır. Eğer geçişli ise, Nokta define eksi olmak Fixnum gibi:point = Point.new(100,100) point - 20 #=> (80,80) 20 - point #=> (-80,-80)
CEVAP
Kısa cevap: how Matrix is doing it check out.
Fikri coerce Point sınıf işlemleri nasıl yapacağını bilen equivalent_something nesne something temelde eşdeğer olduğu ama [equivalent_something, equivalent_self] döndürür. Matrix lib, Matrix::Scalar Numeric herhangi bir nesne oluşturmak ve bu sınıfın Matrix Vector üzerinde işlem yapmak için nasıl bilir.
Noktaları adres için:
Evet, kendi yazarsa kodunuzu başkaları tarafından genişletilebilir olmak istersen, sen de yapmak gerekir, ancak doğrudan Yakut (79 ** çağrı kontrol edin). Eğer
Point#*tanımadığı bir tartışma geçti, örneğinarg.coerce(self)aramaPointcoercekendisi için tartışmayı bu soruyu sormazdın.Evet, 2 öğeleri
b_equiv, a_equiv = a.coerce(b)gibi bir Dizi olmalıEvet. Ruby yerleşik türleri için yapar, ve genişletilebilir olmasını istiyorsanız, kendi özel bir tür için de:
def *(arg) if (arg is not recognized) self_equiv, arg_equiv = arg.coerce(self) self_equiv * arg_equiv end endFikri
Fixnum#*değiştirmeniz gerekmiyor. Eğer bağımsız ** 72, bir sonra çünkü bir şey, örneğin biliyorsun değil miPoint#coercearayarak ister.Geçişlilik (ya da aslında commutativity) operatör, her zaman doğru sırayla denir, çünkü gerekli değildir. Sadece geçici olarak alınan ve değişken döner olan 74 ** Ara.
,==, vb gibi operatörlerin commutativity sigortalanır yerleşik bir mekanizma yok...
Eğer birisi kısa, kesin ve net bir açıklama ile resmi belgelere geliştirmek için gelip eğer, bir yorum bırakın!

Nasıl bir kesildi bir yerine tam bir g...
Diziler ve Karma için IRB baskı yapı y...
Nasıl Ruby anahtarı bir ifade yazabili...
Nasıl 'dosyalarda grup' gerç...
Nasıl Ruby on Rails geçerli mutlak URL...