Як налагодити сценарії Ruby [закрито]


153

Я скопіював з Інтернету наступний код Ruby і вніс кілька змін, але він не працює.

Що я можу зробити, щоб налагодити програму самостійно?


1
Голосування за повторне відкриття. ОП очевидно бажає налагодження GDB-сходинки.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Відповіді:


145

Використовуйте Pry ( GitHub ).

Встановити через:

$ gem install pry
$ pry

Потім додайте:

require 'pry'; binding.pry

у вашу програму.

Станом pry0.12.2 однак, є не команди немає навігації , такі як next, breakі т.д. Деякі інші дорогоцінні камені , крім того , забезпечити це, дивись, наприклад pry-byedebug.


10
Я також рекомендую використовувати Pry (безумовно, зміну життя!) .. Після встановлення та необхідності у вашій програмі встановити точку перерви так само просто, як і писати binding.pry. Він також оснащений кольоровим завершенням, пошуку документації та можливістю динамічного редагування та перезавантаження методу ..
Андреа Фіоре

5
Домашня сторінка Pry доступна тут: pryrepl.org .
shadowbq

4
Pry/ byebugчудово, але не як ваш перший крок при налагодженні. У більшості випадків збільшення винятку з raise object.inspectвирішить вашу проблему швидше, ніж відкриття сеансу irb. Я рекомендую використовувати лише налагоджувачі консолі ще раз, коли прості рішення, такі як підняття виключення, не зможуть вирішити вашу проблему.
Келсі Ханнан

3
Чи існує спосіб одномоментного коду pry? Я не міг знайти, як це зробити; і саме цього я очікую від налагоджувача.
jpetazzo

2
@jpetazzo так, набравши 'наступний'
marcbest

114
  1. У Рубі:

    ruby -rdebug myscript.rb 

    тоді,

    • b <line>: поставити крапку
    • і n(ext)або s(tep)іc(ontinue)
    • p(uts) для відображення

    (як-от налагодження perl)

  2. У Rails: Запустіть сервер за допомогою

    script/server --debugger

    і додати debuggerв код.


7
-rdebug - сміття. І невтримані. Використовуйте Pry (див. Іншу відповідь).
Snowcrash

3
@SnowCrash - Чому ти кажеш, що -r debugце сміття?
sid smith

8
з -rdebug: не потрібно змінювати вихідний файл для налагодження
germanlinux

2
Для нової програми Ruby / Rails Pry - правильна відповідь. Але я витратив більше години, намагаючись знайти стародавню версію Pry для запуску програми Rails 2.2 із конкретною версією вимог facetsдо дорогоцінних каменів, і це не вдалося. Для стародавніх додатків Rails ruby-debugце трохи неприємно, але виконує роботу.
Abe Voelker

56

Як баністери рекомендується: використовуйте прий! Я можу лише погодитися з цим.

pry - це набагато краще відбиття, ніж irb.

Вам потрібно додати

require 'pry'

у свій вихідний файл, а потім додайте точку перерви у вихідний код, додавши

binding.pry

в тому місці, де ви хочете подивитися на речі (це як запуск точки перелому в класичному середовищі IDE)

Як тільки ваша програма потрапить на

binding.pry

рядок, ви будете кинуті прямо у відбиток програм, з усім контекстом вашої програми прямо під рукою, так що ви можете просто вивчити все навколо, дослідити всі об'єкти, змінити стан і навіть змінити код на льоту.

Я вважаю, що ви не можете змінити код методу, який ви зараз перебуваєте, тому ви можете, на жаль, не змінити наступний рядок, який буде виконуватися. Але гарний рубіновий код все одно має тенденцію бути однорядним ;-)


30

Налагодження шляхом підвищення винятків є набагато простіше , ніж мружачись черезprintзаяву журналу, і для більшості помилок, його зазвичай набагато швидше , ніж відкриття КРПА відладчикаякpryабоbyebug. Ці інструменти не завжди повинні бути вашим першим кроком.


Швидке налагодження Ruby / Rails:

1. Швидкий метод: підняти Exceptionтоді і .inspectйого результат

Швидкий спосіб налагодження Ruby (особливо Rails) код для raiseвиключення по шляху виконання вашого коду при виклику .inspectна метод або об'єкт (наприклад foo):

raise foo.inspect

У наведеному вище коді raiseзапускає, Exceptionщо зупиняє виконання вашого коду , і повертає повідомлення про помилку, яке зручно містить .inspectінформацію про об'єкт / метод (тобто foo) у рядку, який ви намагаєтеся налагодити.

Ця методика корисна для швидкого вивчення об'єкта чи методу ( наприклад, це nil? ) Та для негайного підтвердження того, чи рядок коду взагалі виконується в заданому контексті.

2. Відступ: Використовуйте налагоджувач IRB на рубіні, як byebugабоpry

Тільки після того, як ви отримаєте інформацію про стан потоку виконання ваших кодів, вам слід розглянути можливість переходу до налагоджувача ruby ​​gem irb, як pryабо, byebugде ви зможете більш глибоко заглибитися у стан об'єктів у вашому шляху виконання.


Загальні поради для початківців

Коли ви намагаєтеся налагодити проблему, корисна порада завжди: читайте повідомлення про помилку! @ # $ Ing (RTFM)

Це означає, що уважно і повністю читайте повідомлення про помилки, перш ніж діяти, щоб зрозуміти, що він намагається сказати вам. Під час налагодження задайте такі ментальні запитання в такому порядку , читаючи повідомлення про помилку:

  1. На який клас посилається помилка? (тобто чи є у мене правильний клас об’єктів чи це мій об’єкт nil? )
  2. На який метод посилається помилка? (тобто їх тип у методі; чи можу я назвати цей метод на об'єкті типу / класу? )
  3. Нарешті, використовуючи те, що я можу зробити з двох останніх запитань, які рядки коду слід досліджувати? (пам’ятайте: останній рядок коду в трасі стека не обов'язково там, де лежить проблема.)

У сліді стека зверніть особливу увагу на рядки коду, що надходять з вашого проекту (наприклад, рядки, починаючи з, app/...якщо ви використовуєте Rails). 99% часу проблема пов'язана з власним кодом.


Щоб проілюструвати, чому інтерпретувати в цьому порядку важливо ...

Наприклад, повідомлення про помилку Ruby, яке бентежить багатьох початківців:

Ви виконуєте код, який у якийсь момент виконується як такий:

@foo = Foo.new

...

@foo.bar

і ви отримуєте помилку, яка говорить:

undefined method "bar" for Nil:nilClass

Початківці бачать цю помилку і вважають, що проблема barне визначена . Це не. У цій помилці справжня частина, яка має значення:

for Nil:nilClass

for Nil:nilClassозначає, що @fooце Ніл! @fooне є Fooзмінною екземпляра! У вас є об’єкт, який є Nil. Коли ви бачите цю помилку, просто рубін намагається сказати вам, що метод barне існує для об'єктів класу Nil. (ну так! оскільки ми намагаємось використовувати метод для об’єкта класу Fooне Nil).

На жаль, через те, як написана ця помилка ( undefined method "bar" for Nil:nilClass), її легко влучити в думку, що ця помилка пов'язана з barбуттям undefined. Якщо не читати уважно, ця помилка призводить до того, що початківці помилково переходять до деталей barметодуFoo , повністю не пропускаючи ту частину помилки, яка натякає на те, що об'єкт неправильного класу (у даному випадку: nil). Це помилка, яку легко уникнути, прочитавши повідомлення про помилки в повному обсязі.

Підсумок:

Завжди уважно читайте все повідомлення про помилку перед початком налагодження. Це означає: Завжди спочатку перевіряйте тип класу об'єкта у повідомленні про помилку , а потім його методи , перш ніж ви почнете вмикатись у будь-який стек-трек чи рядок коду, де, на вашу думку, може статися помилка. Ці 5 секунд можуть заощадити 5 годин розчарування.

tl; dr: Не косіть журнали друку: створюйте винятки або використовуйте налагоджувач irb замість цього. Уникайте кролячих дірок, уважно читаючи помилки перед налагодженням.


3
Хоча я згоден з вами, що читання журналів друку є втомливим, я вважаю, що рекомендувати в першу чергу не використовувати налагоджувач - це дуже погана порада. Додавання точки перерви та запуск її точно такі ж зусилля, як і підняття винятку, але це дає повний огляд поточного стану програми. Якщо в результаті перевірки сумнівного стану виникають будь-які додаткові запитання, ви можете інтерактивно ознайомитися, замість того, щоб додавати ще один виняток та перезавантажувати програму.
Патрік Р.

2
@PatrickR. На мій досвід, налагоджувачі IRB не є хорошим першим кроком, коли ви все ще намагаєтесь детально розібратися в тому, де проблема у вашому коді. Додавання та видалення багатьох точок зупинки IRB займає більше часу, ніж додавання винятків, і не дайте однозначних відповідей про контрольний потік вашого коду таким чином, як винятки можуть початківцям усунути погані припущення. Точки прориву IRB також легко забути, викликаючи плутанину, коли запити висять. Якщо ви точно знаєте , де проблема, і вам потрібно налагодити її стан, тоді обов'язково почніть з налагоджувача IRB. Але часто це неправда.
Келсі Ханнан

1
Га! Читання повідомлень про помилки корисне для Ruby, але інших мов сценарію? Я не можу звинувачувати ОП у тому, що навіть не набридав.
kayleeFrye_onDeck

1
Моя початкова реакція була схожа на @PatrickR., Але я все-таки спробував це. Зрештою, я вважаю це поганою порадою чи, можливо, найкращим чином, порадою, адаптованою до іншого випадку використання, ніж у мене. Зокрема, у випадку, коли (а) не використовують Rails та (b) мають неправильний результат, але не виникають помилки чи винятки, тобто код обчислює число, це просто неправильне число. Спроба ітеративно вгадати, де зробити програму, яка б інакше виконувала збій, - це стратегія, але це більше роботи, оскільки мені доведеться продовжувати перезапуск і повторний запуск. Кожен цикл має свій час пуску, який витрачається витрачено.
Цегла

20
  1. Роздрукуйте змінні, коли це можливо. (Це називається налагодження printf) Це можна зробити, запустивши

    STDERR.puts x.inspect

    або

    STDERR.puts "Variable x is #{x.inspect}"

    Якщо ви хочете , щоб зробити це простіше набрати, то ви можете використовувати exemplor камінь.

  2. Увімкніть попередження Якщо ви працюєте, rubyто запустіть його за допомогою -wперемикача (наприклад, ruby -w script.rb). Якщо ви запускаєте його з irb і використовуєте версію рубіну до 1.9.2, введіть $VERBOSE = trueна початку сеансу. Якщо ви неправильно написали змінну екземпляра, ви отримаєте попередження

    попередження: змінна інстанція @valeusне ініціалізована

  3. Зрозумійте поняття бінарного відбивання (наступна цитата - " Практики спритного розробника" )

    Розділіть проблемний простір навпіл і подивіться, яка половина містить проблему. Потім знову розділіть цю половину і повторіть.

  4. Якщо ви успішно працюєте з двійковим відбивачем, ви можете виявити, що є одна лінія, яка не робить те, що ви очікуєте. Наприклад

    [1, 2, 3].include?([1,2])

    дає значення false, навіть якщо ви думаєте, що воно повернеться true. У такому випадку ви можете переглянути документацію. Веб-сайти для документації включають ruby-doc.org або APIdock . В останньому випадку слід ввести include?поруч із лупою біля правого верхнього кута, вибрати те, include?що знаходиться Arrayпід ним (якщо ви не знаєте, що таке клас [1, 2, 3], введіть [1, 2, 3].classirb), і ви отримаєте включити? (Масив) , який описує, що він робить.

    Однак якщо документація не допомагає, ви, швидше за все, отримаєте хорошу відповідь, якщо зможете задати питання про те, як певна лінія не робить те, що слід, а не чому весь сценарій не робить того, що воно повинно.


7

видаляє всі речі

Ласкаво просимо у 2017 ^ _ ^

Гаразд, тому, якщо ви не проти спробувати новий IDE, ви можете зробити наступне безкоштовно .

Швидкі інструкції

  1. Встановити vscode
  2. Встановіть Ruby Dev Kit, якщо ви ще цього не зробили
  3. Встановіть розширення Ruby, ruby-linter та ruby-rubocop для vscode
  4. Вручну встановлюйте будь-які дорогоцінні камені rubyide / vscode-ruby , якщо це потрібно
  5. Налаштуйте свої launch.jsonдля використання "cwd"та та "program" поля за допомогою {workspaceRoot}макросу
  6. Додайте поле під назвою "showDebuggerOutput"та встановіть йогоtrue
  7. Увімкніть точки перерви скрізь у налаштуваннях налагодження як "debug.allowBreakpointsEverywhere": true

Детальні інструкції

  1. Завантажити Visual Studio Code aka vscode; це не те саме, що Visual Studio . Це безкоштовно, невелика вага і, як правило, позитивно сприймається.
  2. Встановіть комплект Ruby Dev; слід дотримуватися вказівок на їхній репо тут: https://github.com/oneclick/rubyinstaller/wiki/Development-Kit
  3. Далі ви можете встановити розширення через веб-браузер або всередині IDE; це всередині IDE. Якщо ви вибрали інше, можете піти сюди . Перейдіть до частини розширень vscode; ви можете зробити це декількома способами, але найвірогіднішим у майбутньому методом буде, мабуть, удари F1та введення тексту, extпоки не стане доступною опція під назвою Розширення: Встановити розширення . Альтернативи є CtrlShiftxі з верхнього рядка меню,View->Extensions
  4. Далі вам потрібні наступні розширення; вони не на 100% необхідні, але я дозволю вам вирішити, що слід тримати після того, як ви заробили дещо:
    • Рубін; автор розширення Peng Lv
    • рубін-рубокоп; розширення автора мізогі
    • рубін-лайнер; автор розширення Коді Гувер
  5. Всередині каталогу вашого сценарію рубіну .vscodeми створимо каталог через командний рядок, який називається, і там ми будемо, але файл, який називається, launch.jsonде ми будемо зберігати деякі параметри конфігурації.
    • launch.json зміст

{ "version": "0.2.0", "configurations": [ { "name": "Debug Local File", "type":"Ruby", "request": "launch", "cwd": "${workspaceRoot}", "program": "{workspaceRoot}/../script_name.rb", "args": [], "showDebuggerOutput": true } ] }

  1. Дотримуйтесь вказівок авторів розширень щодо встановлення вручну дорогоцінних каменів. Зараз він розміщений тут: https://github.com/rubyide/vscode-ruby#install-ruby-dependitions
  2. Ви, напевно, захочете можливість ставити точки прориву куди завгодно; відключення цієї опції може призвести до плутанини. Для цього ми перейдемо до верхньої панелі меню та виберемо File->Preferences->Settings(або Ctrl,) та прокручуємо, поки не дістанешся до Debugрозділу. Розгорніть і шукайте поле під назвою "debug.allowBreakpointsEverywhere"- виберіть це поле та натисніть на маленьку піктограму, що виглядає олівцем, і встановіть її true.

Виконуючи усі ці цікаві речі, ви зможете встановити точки перерви та налагодження в меню, подібному до цього, на середину 2017 року та більш темній темі: введіть тут опис зображенняз усіма цікавими матеріалами, такими як стек викликів, переглядач змінних тощо.

Найбільший PITA - це 1) встановлення попередніх запитів і 2) запам'ятовування для налаштування .vscode\launch.jsonфайлу. Тільки №2 повинен додавати будь-який багаж до майбутніх проектів, і ви можете просто скопіювати достатньо загальну конфігурацію, як перелічена вище. Напевно, є більш загальне розташування конфігурацій, але я не знаю, що знаходиться вгорі голови.


Зараз 2018 рік, 😉 але, на жаль, ви все ще не можете налагодити одиничний тест за допомогою перелічених тут плагінів… ite Досить сумно.
Мсьє,

1
@MonsieurDart Коли я писав це, він був призначений для основної налагодження сценаріїв рубіну. Мені нічого не знайоме конкретно про одиничні тести. Якщо ця відповідь невірна або застаріла, повідомте мені про те, що потребує уваги та будь-яку інформацію, яка може допомогти прискорити процес.
kayleeFrye_onDeck

Привіт @kayleeFrye_onDeck! Ваша відповідь чудова, я цілком це вам даю. Але, востаннє, коли я перевіряв плагін Рубі Пенґ Лв на наявність VSC, він не зміг встановити точки перелому всередині тесту одиниці (або будь-якого іншого тесту). Це було одним із відомих обмежень плагіна. Я думаю, що люди повинні знати це, перш ніж намагатися налаштувати свій примірник VSC: це потребує часу, а для багатьох людей проведення тестів - це спосіб номер один для написання та налагодження коду. 😊
Мсьє,

6

Я настійно рекомендую це відео, щоб на даний момент вибрати відповідний інструмент для налагодження нашого коду.

https://www.youtube.com/watch?v=GwgF8GcynV0

Особисто я б виділив дві великі теми у цьому відео.

  • Pry є приголомшливим для налагодження даних, "pry - це провідник даних" (sic)
  • Здається, налагоджувач краще відладжувати крок за кроком.

Це мої два центи!


6

Всі інші відповіді вже дають майже все ... Просто невелике доповнення.

Якщо ви хочете отримати ще один IDE-подібний налагоджувач (не-CLI) і не боїтеся використовувати Vim в якості редактора, я пропоную плагін Vim Ruby Debugger для цього.

Його документація досить проста, тому переходьте за посиланням і дивіться. Коротше кажучи, це дозволяє встановити точку розриву в поточному рядку в редакторі, переглядати локальні змінні у чудовому вікні під час паузи, переходити / входити - майже всі звичайні функції налагодження.

Для мене було дуже приємно використовувати цей відладчик vim для налагодження програми Rails, хоча багаті здібності реєстраторів Rails майже позбавляють від нього потреби.


6

Я щойно виявив цей дорогоцінний камінь (перетворює Pry в налагоджувач для MRI Ruby 2.0+)

https://github.com/deivid-rodriguez/pry-byebug

Встановити за допомогою:

gem install pry-byebug

а потім використовувати точно так само pry, позначте лінію, яку потрібно перервати:

require 'pry'; binding.pry

В відміну від ванілі підглядати однак, цей дорогоцінний камінь має кілька ключових GDB-як навігація команди , такі як next, stepі break:

break SomeClass#run            # Break at the start of `SomeClass#run`.
break Foo#bar if baz?          # Break at `Foo#bar` only if `baz?`.
break app/models/user.rb:15    # Break at line 15 in user.rb.
break 14                       # Break at line 14 in the current file.

5
  1. Ви можете друкувати свої змінні попутно
  2. Увімкніть -wпрапор (попередження)
  3. Використовуйте такий інструмент, як рубін-налагодження

2
Додам, що irbце відмінне стартове місце. Спробуйте використовувати irb з невеликими сумнівними шматками. Я люблю ruby-debug (ruby-debug19 для Ruby 1.9+), тому що це легко зупинити запущену програму, вивчити змінні, потрапити в irb, а потім продовжувати працювати.
Олов'яний чоловік

5

Щоб легко налагодити сценарій оболонки Ruby, просто змініть його перший рядок з:

#!/usr/bin/env ruby

до:

#!/usr/bin/env ruby -rdebug

Потім кожен раз, коли відображається консоль налагодження, ви можете вибрати:

  • cдля продовження (до наступного винятку, точки перерви або рядка з:) debugger,
  • n для наступного рядка,
  • w/ whereдля відображення кадру / стека виклику,
  • l щоб показати поточний код,
  • cat показувати точки лову.
  • h для отримання додаткової довідки.

Дивіться також: Налагодження за допомогою налагодження ruby-debug , ключові ярлики для дорогоцінного каміння ruby-debug .


Якщо сценарій просто зависає, і вам потрібен зворотній слід, спробуйте скористатися lldb/ gdblike:

echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)

а потім перевірте передній план процесу.

Замініть lldbна, gdbякщо працює краще. Префікс sudoдля налагодження процесу, що не належить до власності.


1
ruby-debug виглядає досить застаріло. Git repo для ruby-debug має лише один прихильність на цей рік - це все ще активно підтримується?
Ендрю Грімм

Він також здається, що він упакований з рубіном, що чудово, коли ти перебуваєш у крайній частині. Чудова відповідь!
Breedly

5

Починаючи з Ruby 2.4.0, легше запустити сеанс відповіді IRB в середині будь-якої програми Ruby. Поставте ці рядки в точку програми, яку потрібно налагодити:

require 'irb'
binding.irb

Ви можете запустити Ruby-код і роздрукувати локальні змінні. Введіть Ctrl + D або, quitщоб закінчити REPL і нехай програма Ruby продовжує працювати.

Ви також можете використовувати putsта pроздрукувати значення зі своєї програми під час роботи програми.


4

Якщо ви використовуєте RubyMine , налагодження рубінових скриптів просте і просте.

Припустимо, у вас є сценарій Ruby hello_world.rb

1. Встановити точки перерви

Встановіть точку розриву в рядку 6, як показано нижче.

введіть тут опис зображення

2. Почніть налагодження

Тепер ви можете просто запустити налагоджувач для запуску сценарію:

введіть тут опис зображення

введіть тут опис зображення

3. Огляньте змінні тощо.

Тоді, коли виконання досягне точки розриву, ви зможете перевірити змінні тощо.

введіть тут опис зображення

Додаткова інформація для довідки

  1. Якщо ви хочете використовувати RubyMine для віддаленої налагодження , ви можете зробити це.
  2. Якщо ви хочете використовувати RubyMine для віддалених рейок налагодження, що працюють всередині докера , це також просто.

Чи є у нас спосіб налагодження зовнішніх бібліотек у RubyMine?
Am33d

2

налагодження printf

Завжди існувала суперечка щодо методів налагодження, деякі люблять налагоджувати виписки на друку, інші люблять копати глибоко за допомогою налагоджувача.

Я б запропонував спробувати обидва підходи.

Насправді один із старих чоловіків Unix нещодавно сказав, що налагодження printf - це більш швидкий шлях до нього в певні моменти.

Але якщо ви новачок на якійсь роботі і вам потрібно зрозуміти велику частину коду, тоді дійсно корисно переступити туди, поставивши туди-сюди деякі точки прориву, разом з нею, як це працює.

Це повинно дати вам деяке розуміння того, як плетений код.

Якщо ви новачок у програмі інших народів, це може допомогти вам перейти туди.

Ви швидко дізнаєтесь, чи влаштували вони це розумно, чи це просто купа лайна.


це, без сумніву, найкраща відповідь ,,, це залежить
menriquez

2

Добре, у рубіновій стандартній конвеєрі є простий у використанні налагоджувач консолі, що нагадує gdb: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html Не потрібно встановлювати зайвих дорогоцінних каменів. Сценарії Rails можуть бути налагоджені і таким чином.

напр

def say(word)
  require 'debug'
  puts word
end

1

Мати всіх налагоджувачів - це звичайний старий екран друку. Здебільшого, напевно, ви хочете оглянути лише прості об’єкти, швидкий і простий спосіб такий:

@result = fetch_result

p "--------------------------"
p @result

Це дозволить роздрукувати вміст @result в STDOUT з рядком навпроти для легкої ідентифікації.

Бонус, якщо ви використовуєте рамку, здатну до автоматичного завантаження / перезавантаження, як Rails, вам навіть не потрібно буде перезавантажувати додаток. (Якщо код, який ви налагоджуєте, не перезавантажується через специфічні параметри рамки)

Я вважаю, що це працює для 90% випадків використання для мене. Ви також можете використовувати рубін-налагодження, але я вважаю, що це переважає більшу частину часу.


1

Існує безліч налагоджувачів з різними можливостями, на основі яких ви робите вибір. Мої пріоритети були задоволені при-ходами, які були:

  • швидко зрозуміла інформація про те, як користуватися
  • інтуїтивні кроки (як-от легкий перехід до блоків)
  • "відступаючи" (pry-ходи частково задовольняють потребу)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.