จะรับชื่อวิธีการโทรได้อย่างไร?


161

มีวิธีในทับทิมเพื่อค้นหาชื่อวิธีการโทรภายในของวิธี?

ตัวอย่างเช่น:

class Test
  def self.foo
    Fooz.bar
  end
end

class Fooz
  def self.bar
    # get Test.foo or foo
  end
end



ไม่ซ้ำกันของ "รับชื่อของวิธีการดำเนินการในปัจจุบันในทับทิม" คำถามนี้ถามชื่อของวิธีการโทรไม่ใช่ชื่อของวิธีปัจจุบัน
Wayne Conrad

คำตอบ:


210
puts caller[0]

หรือบางที...

puts caller[0][/`.*'/][1..-2]

5
ใช่เห็น Kernel # caller หรือที่รู้จักว่าruby-doc.org/core-1.8.7/classes/Kernel.html#M001073
DigitalRoss

10
ที่ให้ชื่อของวิธีการโทร แต่มันไม่ได้ให้การบ่งชี้ใด ๆ ที่โมดูลหรือชั้นเรียนเป็นวิธีการที่ เป็นไปได้ไหม
Thomthom

@thomthom ใช่ว่าเป็นไปได้ที่คุณสามารถเรียก self.class.name เพื่อดูชื่อคลาส
Thorin

การใช้ regex ดีเยี่ยมเป็นดัชนีสตริง! ยังสามารถใช้caller[0][/`(.*)'/,1]
aks

1
ดูเหมือนจะใช้งานไม่ได้กับ Rails 5.2.1 ใน Rails "block in make_lambda"ตัวควบคุมผลตอบแทนนี้ ฉันเดาว่านี่สำหรับ Ruby เท่านั้น
dcangulo

164

ใน Ruby 2.0.0 คุณสามารถใช้:

caller_locations(1,1)[0].label

มันได้เร็วขึ้นมากกว่าวิธีทับทิม 1.8+:

caller[0][/`([^']*)'/, 1]

จะรวมอยู่ในbackportsเมื่อฉันได้รับเวลา (หรือคำขอดึง!)


เป็นที่น่าสังเกตว่านี่ไม่สามารถใช้ได้ใน Rubinius
Max

1
หากคุณใช้แงะคุณต้องเพิกเฉยกับการสอดรู้สอดเห็นสอดรู้สอดเห็น ... ดูเหมือนจะไม่มีทางแก้ปัญหาเริ่มต้นสำหรับสิ่งนั้น
dtc

6
ตอนนี้ดูเหมือนว่าจะเป็นcaller_locations[0].labelRuby 2.2.0 ไม่เช่นนั้นคุณจะได้send_actionผลลัพธ์เสมอ
brcebn

1
เราจะได้รับวิธีการโทรแอพเท่านั้นและไม่สนใจการเรียกเฟรมเวิร์ก
เมทริกซ์

31

ใช้caller_locations(1,1)[0].label(สำหรับทับทิม> = 2.0)

แก้ไข : คำตอบของฉันกำลังบอกว่าจะใช้__method__แต่ฉันผิดมันกลับชื่อวิธีปัจจุบัน


1
@OswaldoFerreira ขอบคุณพบว่ามันในดังนั้นในคำตอบที่ใดที่หนึ่งอีก
Dorian

5
นี่ไม่ถูกต้องมันส่งคืนวิธีปัจจุบันไม่ใช่วิธีที่เรียกว่าวิธีปัจจุบัน ...
801

1
ทำงานเหมือนจับใจ ดูเหมือนว่าจะเร็วกว่าวิธีก่อน 2.0 มาก
Dr.Strangelove

21

ฉันใช้

caller[0][/`([^']*)'/, 1]

4
อะไรคือข้อดีของวิธีการนี้มากกว่า DigitalRoss?
Andrew Grimm

2
สะอาดและแม่นยำยิ่งขึ้น แทนที่จะทำการค้นหาแล้วใช้วิธีอาร์เรย์เพื่อแยกอักขระที่ไม่ต้องการตามตำแหน่ง (ซึ่งอาจไม่ถูกต้อง)
ใหม่ Alexandria

2
ทำไมไม่ใช้ผู้โทร [0] [/ `(. *) '/, 1]? ฉันไม่ใช่กูรูเกี่ยวกับการแสดงออกปกติ แต่ดูเหมือนว่าจะทำงาน
collimarco

7
@collimarco ตราบใดที่สตริงไม่มีส่วน'เกินที่คุณกำลังมองหา (และฉันคิดว่ามันไม่สามารถทำได้) ผลลัพธ์จะเหมือนกันอย่างแน่นอน อย่างไรก็ตาม[^']*จะทำงานได้ดีขึ้นเนื่องจากเอ็นจิ้น regex จะหยุดพยายามจับคู่ส่วนนั้นในช่วงเวลาที่มันมาถึง'(เวอร์ชั่นของคุณจะไปจนจบจากนั้นย้อนกลับเพราะมันไม่พบ'จุดสิ้นสุด) ความแตกต่างนั้นค่อนข้างเล็กน้อยในกรณีนี้ แต่มันก็เป็นนิสัยที่ดีที่จะหลีกเลี่ยง.ใน regexes ถ้าเป็นไปได้
Thor84no


3

แต่คุณสามารถเขียนมันเป็นฟังก์ชั่นห้องสมุดและโทรออกได้ทุกที่ที่ต้องการ รหัสจะเป็นดังนี้:

module CallChain
  def self.caller_method(depth=1)
    parse_caller(caller(depth+1).first).last
  end

  private

  # Copied from ActionMailer
  def self.parse_caller(at)
    if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
      file   = Regexp.last_match[1]
      line   = Regexp.last_match[2].to_i
      method = Regexp.last_match[3]
      [file, line, method]
    end
  end
end

เพื่อให้วิธีการโมดูลข้างต้นคุณต้องเรียกเช่นนี้: caller = CallChain.caller_method

รหัสอ้างอิงจาก


1
ยินดีต้อนรับลิงก์ไปยังโซลูชันที่เป็นไปได้ แต่โปรดเพิ่มบริบทรอบลิงก์เพื่อให้ผู้ใช้เพื่อนของคุณมีความคิดว่ามันคืออะไรและเพราะเหตุใด อ้างถึงส่วนที่เกี่ยวข้องที่สุดของลิงค์สำคัญเสมอในกรณีที่เว็บไซต์เป้าหมายไม่สามารถเข้าถึงหรือออฟไลน์อย่างถาวร คำนึงถึงความเป็นอยู่เชื่อมโยงไปยังเว็บไซต์ภายนอกเป็นเพียงเหตุผลที่เป็นไปได้ว่าเป็นเพราะเหตุใดและคำตอบบางคำตอบถูกลบไปอย่างไร .
Xavi López

@ XaviLópezได้อัปเดตคำตอบแล้วโปรดแก้ไขถ้าฉันทำผิดหรือผิดพลาด ... ขอบคุณสำหรับคำแนะนำที่ดี :)
amit karsale

1
ขอบคุณสำหรับการปรับปรุงคำตอบของคุณ น่าเสียดายที่ฉันไม่มีความรู้เกี่ยวกับทับทิมเพียงพอที่จะสามารถแสดงความคิดเห็นได้อย่างถูกต้องเกี่ยวกับโพสต์นี้ แต่คำตอบดูเหมือนจะไม่เป็นไร ฉันลบ downvote แล้ว ขอให้โชคดี :-)
Xavi López

2

หากต้องการดูข้อมูลผู้โทรและรับสายในภาษาใด ๆ ไม่ว่าจะเป็น ruby ​​หรือ java หรือ python คุณจะต้องดูที่การติดตามสแต็กเสมอ ในบางภาษาเช่น Rust และ C ++ มีตัวเลือกในตัวคอมไพเลอร์เพื่อเปิดกลไกการทำโปรไฟล์บางประเภทที่คุณสามารถดูได้ในระหว่างเวลาทำงาน ฉันเชื่อว่ามีอยู่จริงสำหรับ Ruby ที่เรียกว่า ruby-prof

และดังที่ได้กล่าวไว้ข้างต้นคุณสามารถมองเข้าไปในกองการประมวลผลสำหรับทับทิม Stack การประมวลผลนี้เป็นอาร์เรย์ที่มีวัตถุตำแหน่งย้อนหลัง

สิ่งสำคัญที่คุณต้องรู้เกี่ยวกับคำสั่งนี้มีดังนี้:

ผู้เรียก (start = 1, length = nil) → array หรือ nil

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.