SORU
9 Mayıs 2010, Pazar


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:

Point Fixnum (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:

  1. point.coerce(3) kim çağırır? Ruby otomatik olarak mı, yoksa bazı kod içinde istisna yakalama Fixnum * yöntem mi? Ya da bilinen türlerinden biri bilmiyor, o zaman coerce arama case Beyannamenin değil mi?

  2. coerce her zaman 2 öğeleri bir dizi dönmek gerekiyor mu? Hiçbir dizi olabilir mi? Ya bu 3 elemanları bir dizi olabilir?

  3. 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 veya Fixnum kod tarafından yapılır? Eğer Fixnum kod 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
    
  4. Ç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.

  5. Point sınıf coerce oldukça genel ve geçişli oldukları için * veya ile ç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
10 Mayıs 2010, PAZARTESİ


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:

  1. 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ğin arg.coerce(self) arama Point coerce kendisi için tartışmayı bu soruyu sormazdın.

  2. Evet, 2 öğeleri b_equiv, a_equiv = a.coerce(b) gibi bir Dizi olmalı

  3. 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
    end
    
  4. Fikri Fixnum#* değiştirmeniz gerekmiyor. Eğer bağımsız ** 72, bir sonra çünkü bir şey, örneğin biliyorsun değil mi Point#coerce arayarak ister.

  5. 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!

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FamilyFeud

    FamilyFeud

    22 AĞUSTOS 2006
  • Nick Pitera

    Nick Pitera

    8 NİSAN 2006
  • MofoHifi Records

    MofoHifi Rec

    15 HAZİRAN 2006