Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

สนุกกับวิธี `วิธีการ`

คุณเคยต้องการที่จะส่งเมธอดไปยังฟังก์ชันที่ใช้บล็อคเท่านั้นหรือไม่? หรือหาว่า 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 ได้