แงะ: แสดงสแต็คให้ฉันดู


102

การใช้ Pry ใน Rails เมื่อฉันกดเบรกพอยต์ในรหัส binding.pry

ฉันอยากรู้ว่าฉันมาที่นี่ได้ยังไงใครเรียกฉันใครเรียกพวกเขา ฯลฯ แต่แปลกฉันไม่เห็นคำสั่งนั้น มีใครรู้บ้าง?

คำตอบ:


51

ใช้ปลั๊กอินpry-stack_explorerซึ่งช่วยให้คุณสามารถเลื่อนขึ้นและลง call-stack (พร้อมupและdown) แสดง callstack (ด้วยshow-stack ) และอื่น ๆ :

ดูที่นี่:

Frame number: 0/64

From: /Users/johnmair/ruby/rails_projects/personal_site/app/controllers/posts_controller.rb @ line 7 PostsController#index:

    5: def index
    6:   @posts = Post.all
 => 7:   binding.pry
    8: end

[1] pry(#<PostsController>)> show-stack

Showing all accessible frames in stack (65 in total):
--
=> #0  index <PostsController#index()>
   #1 [method]  send_action <ActionController::ImplicitRender#send_action(method, *args)>
   #2 [method]  process_action <AbstractController::Base#process_action(method_name, *args)>
   #3 [method]  process_action <ActionController::Rendering#process_action(*arg1)>
<... clipped ...>

[2] pry(#<PostsController>)> up

Frame number: 1/64
Frame type: method

From: /Users/johnmair/.rvm/gems/ruby-2.0.0-p0/gems/actionpack-3.2.8/lib/action_controller/metal/implicit_render.rb @ line 4 ActionController::ImplicitRender#send_action:

    3: def send_action(method, *args)
 => 4:   ret = super
    5:   default_render unless response_body
    6:   ret
    7: end

[3] pry(#<PostsController>)> 

141

หากต้องการทำสิ่งนี้โดยไม่มีปลั๊กอินสอดรู้สอดเห็น (ฉันมีปัญหากับ pry-stack_explorer) ให้ดูที่callerไฟล์.

ฉันมองหาชื่อโปรเจ็กต์ของฉันเพื่อกรองรายการสแต็กรางที่ไม่เกี่ยวข้องทั้งหมดออกไป ตัวอย่างเช่นถ้าฉันใช้ชื่อโครงการarchie:

caller.select {|line| line.include? "archie" }

ซึ่งทำให้ฉันมีร่องรอยสแต็กที่ฉันกำลังมองหา

วิธีที่สั้นกว่าคือ:

caller.select {|x| x["archie"] }

ซึ่งใช้งานได้ดีเช่นกัน


1
นี่มันเยี่ยมมาก ฉันรู้สึกรำคาญเพราะมันมีสแต็คสายสอดรู้สอดเห็นและฉันแค่ต้องการสิ่งที่มาจากแอปพลิเคชันของฉันโดยเฉพาะ +1!
cdpalmer

6
สมบูรณ์แบบ. ฉันเพิ่มคีย์คอมโบไปที่ tmux เพื่อป้อนสิ่งนี้ (ผูก 'B' send-keys '... ^ M') โดยใช้ "ปฏิเสธ" แทนดังนั้นจึงเป็นแบบทั่วไปมากกว่า: caller.reject {|x| x["vendor/bundle"] || x["/.rbenv/versions/"] }
hoodslide

4
ตามความเป็นจริงสำหรับชุมชน Ruby คำตอบเดียวที่มีประโยชน์ถูกฝังอยู่ใต้คำแนะนำเพื่อติดตั้งปลั๊กอินบางตัว
Jesse Dhillon

4
คำตอบนี้สมควรได้รับคะแนนโหวตมากมาย ใช่คุณสามารถติดตั้งสิ่งต่างๆเพิ่มเติมได้ที่ด้านบนของแงะ แต่คุณยังสามารถใช้คุณสมบัติภาษาที่มีอยู่ของ Ruby เพื่อไปให้ไกลที่สุด (แน่นอนว่าไกลพอที่จะตอบคำถามของ OP ได้!)
ตอบ

1
คำตอบนี้ควรเป็นคำตอบที่ถูกต้องเนื่องจากไม่ต้องใช้ปลั๊กอินเพิ่มเติม!
Alvaro Cavalcanti

83

มีpry-backtraceซึ่งแสดง backtrace สำหรับเซสชัน Pry

นอกจากนี้ยังมีwtf? . รายการใดที่เป็น backtrace ของข้อยกเว้นล่าสุด เพิ่มเครื่องหมายคำถามเพื่อดู backtrace หรือเครื่องหมายอัศเจรีย์เพื่อดูทั้งหมด

พิมพ์help in pry เพื่อดูคำสั่งอื่น ๆ ทั้งหมด :)


1
pry-backtraceก็โอเค แต่pry-stack_explorerปลั๊กอินมีประสิทธิภาพมากกว่า (แม้ว่าจะเป็นอัญมณีอื่นปลั๊กอิน)
horseyguy

7
แต่ความจริงก็คือบางครั้งคุณไม่ได้ใช้คุณสมบัติเหล่านั้นทั้งหมด :)
Dzung Nguyen

1

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

ด้านล่างนี้ยังมีประโยชน์สำหรับการติดตามที่มีประสิทธิภาพ https://github.com/pry/pry-stack_explorer


0

ขยายความเกี่ยวกับคำตอบของ Paul Oliver

หากคุณมีรายการวลีที่คุณต้องการยกเว้นอย่างถาวรคุณสามารถทำได้ด้วยคุณสมบัติคำสั่งที่กำหนดเองใน Pry

ใน~/.pryrc:

Pry::Commands.block_command "callerf", "Filter the caller backtrace" do
  output = caller.reject! { |line| line["minitest"] || line["pry"] } 
  puts "\e[31m#{output.join("\n")}\e[0m"
end

การโทรcallerfจะส่งผลให้callerเอาต์พุตถูกกรอง สัญญาณแปลก ๆ รอบ ๆ#{output}คือการระบายสีเพื่อจำลองรูปลักษณ์ดั้งเดิมของcaller. ฉันเอาสีมาจากที่นี่ที่นี่

หรือหากคุณไม่ต้องการสร้างคำสั่งที่กำหนดเองให้ใช้Ctrl+Rเพื่อค้นหาผ่านประวัติคำสั่ง


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