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

Я пытаюсь создать плагин для Discourse, написанный на Ruby. Как обычные пустые файлы, моя программа работает идеально и без ошибок, но когда я пытаюсь адаптировать свой код к контексту плагина, я сталкиваюсь с проблемами, и я не уверен, действительно ли я понимаю, как должна быть реализована вся идея с функциями. Я подумал, что было бы разумно иметь более одного файла, передать функциональность в разных методах и потребовать их в своего рода «основном» файле. Например, получение твитов — это один метод в дополнительном файле, отправка твитов — другой метод в другом файле. В пустом коде ruby ​​он работает нормально, но когда я пытаюсь интегрировать его в файловую структуру плагина, я получаю сообщение об ошибке.

undefined method `my_method' for #<Plugin::Instance:0x00007f9004012fc0> (NoMethodError)

файлы с методами находятся в каталоге lib, а «основной» файл, который называется plugin.rb, находится в основной папке.

так что я пытался

require_relative 'lib/my_method'

и по-другому

require_relative File.expand_path('../lib/my_method.rb', __FILE__)

но я все еще сталкиваюсь с этой ошибкой.

я не определял какие-либо классы или модули или что-то в этом роде, поэтому «файлы методов» буквально начинаются с

def self.my_method

    #my code here
    end 

Может ли это быть причиной того, что я столкнулся с ошибкой выше? Почему он работает как пустой код ruby, но не когда я пытаюсь запустить плагин с rails s на моем экземпляре дискурса? Я все еще довольно новичок в программировании на руби, поэтому, возможно, мой вопрос покажется немного глупым.

Вот ссылка, которая привела меня к созданию плагина:

https://meta.discourse.org/t/beginners-guide-to-creating-discourse-plugins-part-1/30515


person Sebastian    schedule 10.12.2018    source источник


Ответы (1)


К сожалению, ваше понимание методов поверхностно. По сути, любой метод, который вы объявляете в глобальной области, добавляется в класс Object как закрытый метод, поэтому он доступен везде в ваших объектах, потому что они происходят из класса Object и в глобальной области, потому что это область класса Object. Если вы объявляете метод как self.method, вы делаете его методом основного объекта, потому что self ссылается на main, что для вас нежелательно. Чтобы решить эту проблему, вы должны просто удалить себя и написать так:

def my_method
end

Таким образом, этот метод будет добавлен к самому классу объекта, а не к основному объекту. На статью о методах есть ссылка в целом. И еще один один на поведение области верхнего уровня. В этой кодовой ручке вы можете заметить разницу. Кроме того, вам может быть полезно немного изучить Ruby, прежде чем приступить к разработке. Я предлагаю rubymonk. Другая проблема — ваши файлы с одним методом, что не является лучшей практикой для организации рубинового кода. Ruby — действительно объектно-ориентированный язык, и если вам нужно иметь кучу или даже один метод общего назначения, лучше поместить его в модуль или класс, чтобы определить его назначение и роль в приложении, сделать его повторно используемым и отслеживаемым, без загрязнение глобального масштаба.

person Artur Martsinkovskyi    schedule 10.12.2018
comment
Спасибо вроде исправили. Я был уверен, что пробовал это, но, похоже, я ошибался! Большое спасибо за ваш ответ! - person Sebastian; 11.12.2018