Проверка синтаксиса или «компиляция» приложения Ruby on Rails - PullRequest
6 голосов
/ 09 июля 2009

Я новичок в Ruby и недавно столкнулся с проблемой сравнения значений при создании приложения Ruby on Rails. В контроллере у меня было следующее утверждение, которое всегда возвращало false:

if (user.id != params[:id])

Проблема в том, что user.id (который является активной записью) является целым числом, а params [: id] является строкой. Мне потребовалось некоторое время, чтобы понять это, и я наконец изменил это на:

if (user.id != params[:id].to_i)

Теперь оператор работает как положено.

Чтобы избежать этой ошибки в будущем, есть ли способ "скомпилировать" или заставить Ruby предупредить вас, если вы попытаетесь сравнить 2 разных типа? Некоторые другие проблемы, с которыми я столкнулся, которые я хотел бы «проверить при компиляции»:

  • Предупредить меня, если я создам переменную, но не использую ее. Чтобы помочь проверить опечатки в именах переменных.
  • Убедитесь, что метод существует в классе, чтобы я мог избежать опечаток имени метода, а также помочь в рефакторинге, например, если я переименую метод.

В настоящее время я использую Ruby 1.8.6-27 RC2 с Rails 2.3.2 и RadRails IDE для Windows.

Ответы [ 6 ]

5 голосов
/ 09 июля 2009

Сначала проверьте, затем код. Если вы пишете тесты, которые охватывают все ветви вашего приложения, вы получаете гарантию того, что ваш код работает и дает правильные результаты.

РЕДАКТИРОВАТЬ: я должен отметить, что способность сравнивать два типа, не зависящие от имен методов до последней секунды и т. Д., Являются основными функциями Ruby.

Вы вызываете метод не столько, сколько отправляете сообщение объекту. Затем объект отвечает за выяснение того, как обрабатывать метод. В Rails это используется для доступа к столбцам БД в ActiveRecord. Для столбцов нет методов, пока объекту не будет отправлено сообщение с именем столбца.

Статическая типизация в Ruby идет вразрез с системой типизации уток. Часто можно получить полиморфизм бесплатно, не беспокоясь о сложных схемах наследования / интерфейса.

Я предлагаю использовать эти функции и компенсировать неопределенность путем тестирования

2 голосов
/ 09 июля 2009

Ruby не позволяет переопределить оператор == для объекта. В ruby ​​1.8 вы не можете, Ruby 1.9 должен был это делать, но я не смог заставить мой скрипт работать для базовых классов. Хорошо работает для пользовательских объектов.

class Object

  alias :equal_without_warning :==

  def ==(object)
    unless self.class == object.class
      warn("Comparing `#{self.class}' with `#{object.class}'")
    end
    equal_without_warning(object)
  end

end

Предполагая, что я не сделал глупой ошибки кодирования, ответ НЕТ: вы не можете проверить, сравниваете ли вы объекты другого типа.

Кроме того, я бы сказал, что нет. На самом деле Ruby не предназначен для такой работы, это скорее Java-подход, а не стиль Ruby.

1 голос
/ 09 июля 2009

В общем, лучший способ (я знаю), чтобы избежать проблем такого типа для динамических языков и языков сценариев, - это переместить «логику» в методы / команды и написать для них модульные тесты. По сути, все, что может потерпеть неудачу, должно быть проверено. Код на странице должен быть глупой логикой ... вместо того, чтобы отображать только те элементы, которые соответствуют определенным критериям, он должен отображать все элементы и получать этот список элементов из метода, который возвращает только те, которые должны отображаться.

1 голос
/ 09 июля 2009

Руби не должна быть в безопасности. Он позволяет вам сравнивать любые два объекта, и в этом его основная сила. Рельсы были бы невозможны без такого динамичного дизайна.

Даже скомпилированный язык, такой как Java или C, не остановит вас от выполнения == для двух объектов. Как сказал Бен, лучше всего сначала проверить. Осмотрите структуры, с которыми вы работаете. Один из способов получить информацию об объекте Ruby - использовать:

puts object.class
0 голосов
/ 26 октября 2015

Лучшим решением, которое я нашел, была IDE, которая выполняла проверку синтаксиса «на лету», например RubyMine. Я не уверен, что это решило бы мою первоначальную проблему, но это помогло мне найти и исправить несколько других синтаксических ошибок и ошибок компиляции. Спасибо всем за ваши предложения.

0 голосов
/ 13 июля 2009

Две вещи, которые я бы предложил:

One: Прочтите IRB (или скрипт / консоль для рельсов). Обычная практика разработки на динамических языках - это попробовать фрагменты кода внутри «живого» интерпретатора (такого как IRB или консоль rails). Эта практика восходит к самым ранним динамическим языкам, таким как Smalltalk и Lisp. Ruby-debug также очень полезен для устранения неполадок и был бы действительно простым способом выяснить ошибку в вашем примере.

Два: Читайте "Duck Typing". «Типы» и переменные в Ruby работают немного иначе, чем ожидают многие. Насколько я понимаю, переменная типа user.id не имеет типа. Значение , указанное user.id на , имеет тип, но сама переменная не имеет типа. Я полагаю, что это одна из причин, по которой нет инструмента, который бы сообщал вам о вашей ошибке до запуска программы. Сравнение этих двух переменных не является ошибкой, потому что переменные не имеют типа. user.id указывал на целое число в этой точке вашей программы, но было бы совершенно правильно назначить user.id для указания на строку, и тогда это сравнение имело бы гораздо больше смысла. : -)

...