Rayları öğreniyorum ve this thread'u takip ediyorum. to_proc
yöntemiyle takılıyorum. Sembolleri sadece iplere alternatif olarak düşünürüm (onlar dizgeye benziyorlar ama bellek bakımından daha ucuzlar). Simgeler için başka bir şey varsa, lütfen bana söyleyin. Lütfen to_proc
'un ne anlama geldiğini ve ne için kullanıldığını basit bir şekilde açıklayınız.to_proc yöntemi ne anlama geliyor?
cevap
Bazı yöntemler bir blok almak ve bu desen sık bir blok için görünür:
{|x| x.foo}
ve insanlar daha özlü bir şekilde o yazmak istiyorum. Bunu yapmak için, bir sembol, Symbol#to_proc
, örtük sınıf döküm yöntemi ve &
operatörü birlikte kullanılır. Bağımsız değişken konumuna Proc
örneğinin önüne &
koyarsanız, bu bir blok olarak yorumlanır. Proc
örneğinden &
ile başka bir şey birleştirirseniz, örtük sınıf döküm, varsa to_proc
yöntemini kullanarak Proc
örneğini dönüştürmeyi deneyecektir. Bir Symbol
örneği durumunda, bu yolla to_proc
çalışır: Örneğin
:foo.to_proC# => ->x{x.foo}
, bu gibi yazmak varsayalım:
&
operatörü
Proc
örneği olmadığı,
:foo
ile birleştirilir
bar(&:foo)
Bu nedenle, örtük sınıfsal döküm Symbol#to_proc
değerini uygular, bu da ->x{x.foo}
değerini verir. &
şimdi bu geçerli olduğu ve veren bir blok olarak yorumlanır: Bu bir örnek vermektir açıklamaya
bar{|x| x.foo}
kolay yolu.
(1..3).collect {|num| num.to_s} #=> ["1", "2", "3"]
ve
[1,2,3].collect(&:succ) #=> [2, 3, 4]
aynı mı:
(1..3).collect(&:to_s) #=> ["1", "2", "3"]
aynı mı verilen yönteme yanıt veren bir Proc nesnesi geri to_proc
[1,2,3].collect {|num| num.succ} #=> [2, 3, 4]
sembol tarafından. Üçüncü durumda, dizi [1,2,3] toplama yöntemini çağırır ve. succ, Array sınıfı tarafından tanımlanan yöntemdir. Dolayısıyla bu parametre, dizideki her bir elemanı toplamak ve ardılını iade etmenin kısa bir yoludur ve bundan [2,3,4] ile sonuçlanan yeni bir dizi yaratır. Sembol: succ bir Proc nesnesine dönüştürülür, böylece Array'ın succ yöntemini çağırır.
@Dilon +1 örnekler için :) – swapnesh
Benim için en açık açıklama, basit bir uygulama olduğunu görmektir.biraz daha net Birileri
class Symbol # reopen Symbol class to reimplement to_proc method
def to_proc
->(object) { object.send(self) }
end
end
my_lambda = :to_s.to_proc
puts my_lambda.(1) # prints '1'; .() does the same thing as .call()
puts my_lambda.(1).class # prints 'String'
puts [4,5,6].map(&:to_s) # prints "4\n5\n6\n"
puts [4,5,6].map(&:to_s).first.class # prints 'String'
Bu! Bu arada, 'Symbol' sınıfında maymun yama yapmaya çalıştığınız yöntemde 'my_to_proc' olmamalıdır? –
@AgungSetiawan İyi yakalama! Bunun yerine, aramayı my_to_proc yerine toproc çağrısı yapmak için yeniden adlandırdım. –
hala biraz stumped, aşağıdaki kodu çalıştıran şeyler hale getirebileceğini:
class Symbol
def to_proc
proc do |obj|
puts "Symbol proc: #{obj}.send(:#{self})"
obj.send(self)
end
end
end
class Array
def map(&block)
copy = self.class.new
self.each do |index|
puts "Array.map: copy << block.call(#{index})"
copy << block.call(index)
end
copy
end
end
remapped_array = [0, 1, 2].map &:to_s
puts "remapped array: #{remapped_array.inspect}"
Bunlar olmadığında İşte ben reimplementing olsaydı gibi Sembol # to_proc göründüğü aşağıda Symbol.to_proc
veya Array.map
'un gerçek uygulamaları, sadece map &:to_s
ve benzeri çağrıların nasıl çalıştığını göstermek için kullanıyorum basitleştirilmiş sürümleridir.
açıklama +1 :) – swapnesh
Plus için teşekkürler, buna göre , 20 çalışma zamanı boyunca daha hızlı. –
Anladım & proc bir blok veriyor, & x' sonuçta x oluyor ve sonra her şey bir blok veriyor. Ayrıca, Symbol'un to_proc yöntemine sahip olduğunu anlıyorum. Ancak anlamadığım ve bu cevabın eksik olduğunu hissettiğim kısım, sembol ve yöntemlerin nasıl bağlandığıdır. Yani tüm yöntemler aynı zamanda –