คุณเคยต้องการที่จะส่งเมธอดไปยังฟังก์ชันที่ใช้บล็อคเท่านั้นหรือไม่? หรือหาว่า superclasses ของออบเจ็กต์ใดที่ทำลายวิธีการที่คุณพยายามเรียก
สิ่งเหล่านั้นทำได้ง่ายด้วย method
วิธีการ ใช้งานได้ดี และคุณสามารถเรียนรู้เกี่ยวกับการพึ่งพาของคุณ ประหยัดเวลาในการดีบั๊ก และนำโค้ดของคุณไปยังที่ที่จำเป็น
วิธีการที่ง่ายเหมือนแลมบ์ดาส
วิธีการมากมายของ Ruby ใช้บล็อคหรือแลมบ์ดา แต่คุณไม่สามารถส่งเมธอดไปยังวิธีอื่นได้โดยตรง แบบเดียวกับที่คุณทำกับแลมบ์ดา คุณต้องใช้ method
ครั้งแรก:
irb(main):001:0> sin_method = Math.method(:sin)
=> #<Method: Math.sin>
irb(main):002:0> (1..10).map(&sin_method)
=> [0.8414709848078965, 0.9092974268256817, 0.1411200080598672, -0.7568024953079282, -0.9589242746631385, -0.27941549819892586, 0.6569865987187891, 0.9893582466233818, 0.4121184852417566, -0.5440211108893699]
เกิดอะไรขึ้นที่นี่?
บรรทัดแรกเปลี่ยนวิธีการ Math.sin
เป็น method
วัตถุ. เช่นเดียวกับแลมบ์ดาส วัตถุ "วิธีการ" ตอบสนองต่อ "การโทร" method
วัตถุตอบสนองต่อ to_proc
(ขอบคุณเบอนัวต์) จึงสามารถใช้ได้ในที่เดียวกันกับแลมบ์ดา:
irb(main):004:0> sin_method = -> (x) { Math.sin(x) }
=> #<Proc:0x007fe9f90a9bd8@(irb):4 (lambda)>
irb(main):005:0> (1..10).map(&sin_method)
=> [0.8414709848078965, 0.9092974268256817, 0.1411200080598672, -0.7568024953079282, -0.9589242746631385, -0.27941549819892586, 0.6569865987187891, 0.9893582466233818, 0.4121184852417566, -0.5440211108893699]
มาดูบรรทัดแรกกันอีกครั้ง รหัสนี้ใช้แลมบ์ดาทำงานเหมือนกับโค้ดก่อนหน้า โดยใช้ method
.
ขึ้นอยู่กับว่าคุณได้เขียนโค้ดของคุณอย่างไร การได้รับmethod
วัตถุสามารถทำได้ง่ายกว่าการห่อด้วยแลมบ์ดา ดังนั้นเมื่อคุณต้องการแลมบ์ดาและสิ่งที่คุณมีคือเมธอด จำ method
วิธีการ
วิธีการนั้นมาจากไหน
คุณเพิ่งเรียกใช้เมธอดบนออบเจ็กต์ของคุณ และมันทำสิ่งที่คุณไม่คาดคิด อาจมีใครบางคนแทนที่มันหรือแก้ไขลิง คุณคิดอย่างไรกับสิ่งนี้
คุณ สามารถ ขุดผ่านซอร์สโค้ดสักสองสามชั่วโมง แต่ method
มีสองวิธีที่สามารถเร่งความเร็วได้
หากต้องการทราบว่าคลาสใดกำหนดวิธีการที่คุณโทร ให้ใช้ owner
:
irb(main):003:0> Task.new.method(:valid?).owner
=> ActiveRecord::Validations
เมื่อคุณต้องการลงลึกอีกเล็กน้อยและค้นหาว่า ที่ไหน วิธีการถูกกำหนด ใช้ source_location
:
irb(main):004:0> Task.new.method(:valid?).source_location
=> ["/usr/local/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta2/lib/active_record/validations.rb", 55]
source_location
ส่งกลับอาร์เรย์ องค์ประกอบแรกคือเส้นทางไปยังไฟล์ที่มีการกำหนดวิธีการ และองค์ประกอบที่สองคือหมายเลขบรรทัด คุณจะรู้ว่าจะดูที่ไหนต่อไป
การอ่านแหล่งที่มา (โดยไม่ต้องขุด)
เมื่อคุณสามารถหา ที่ไหน มีการกำหนด method ไว้ คุณอาจต้องการดู how มันถูกกำหนดไว้แล้ว
method
ไม่สามารถทำได้ด้วยตัวเอง แต่หากคุณติดตั้ง method_source
gem คุณสามารถดูซอร์สโค้ดได้หลายวิธีจากคอนโซลของคุณ:
irb(main):002:0> puts Task.new.method(:valid?).source
def valid?(context = nil)
context ||= (new_record? ? :create : :update)
output = super(context)
errors.empty? && output
end
=> nil
คุณยังสามารถดูความคิดเห็น:
irb(main):003:0> puts Task.new.method(:valid?).comment
# Runs all the validations within the specified context. Returns +true+ if
# no errors are found, +false+ otherwise.
#
# Aliased as validate.
#
# If the argument is +false+ (default is +nil+), the context is set to <tt>:create</tt> if
# <tt>new_record?</tt> is +true+, and to <tt>:update</tt> if it is not.
#
# Validations with no <tt>:on</tt> option will run no matter the context. Validations with
# some <tt>:on</tt> option will only run in the specified context.
=> nil
สวยน่ากลัวใช่มั้ย? เอกสารของคุณอยู่ในคอนโซลแล้ว!
วิปัสสนาดีมาก
คลาส Ruby ที่ฉันโปรดปรานบางคลาสคือคลาสที่ให้คุณตรวจสอบโค้ดจากภายในโค้ดของคุณ คลาสเช่น Class
, Module
และ method
. ด้วยสิ่งเหล่านี้ คุณสามารถเรียนรู้มากมายเกี่ยวกับโค้ดของคุณในขณะที่ทำงาน และแก้ไขได้ทันที เรียนรู้ชั้นเรียนเหล่านี้ให้ดี ศึกษา API ของชั้นเรียน แล้วคุณจะสามารถทำสิ่งที่น่าทึ่งกับ Ruby ได้