Добавление функциональности в Rails - PullRequest
2 голосов
/ 05 сентября 2008

Я работаю над приложением Rails и собираюсь включить некоторые функции из " Получение имени хоста или IP в Ruby on Rails ", которое я спросил.

У меня проблемы с тем, чтобы заставить его работать. У меня сложилось впечатление, что я должен просто создать файл в каталоге lib, поэтому я назвал его 'get_ip.rb' с содержанием:

require 'socket'

module GetIP
  def local_ip
    orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true  # turn off reverse DNS resolution temporarily

    UDPSocket.open do |s|
      s.connect '64.233.187.99', 1
      s.addr.last
    end
  ensure
    Socket.do_not_reverse_lookup = orig
  end
end

Я также пытался определить GetIP как класс, но когда я делаю обычный ruby script/console, я вообще не могу использовать метод local_ip. Есть идеи?

Ответы [ 3 ]

5 голосов
/ 05 сентября 2008

require загрузит файл. Если этот файл содержит определения классов / модулей, ваш другой код теперь сможет их использовать. Если файл просто содержит код, которого нет ни в одном модуле, он будет запущен так, как если бы он находился в том же месте, что и ваш вызов require (например, PHP include)

include относится к модулям.

Он берет все методы в модуле и добавляет их в ваш класс. Как это:

class Orig
end

Orig.new.first_method # no such method

module MyModule
  def first_method
  end
end

class Orig
   include MyModule
end
Orig.new.first_method # will now run first_method as it's been added.

Существует также extend, который работает как include, но вместо добавления методов как instance методов добавляет их как class методы, например:

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

class SecondClass
  extend MyModule
end
SecondClass.first_method # will call first_method

Обратите внимание, что в этом примере я не создаю никаких новых объектов, просто вызываю метод непосредственно в классе, как если бы он был определен как self.first_method все время.

Итак, поехали: -)

4 голосов
/ 05 сентября 2008

Вы не описали, как вы пытаетесь использовать метод, поэтому я заранее прошу прощения, если это то, что вы уже знаете.

Методы модуля никогда не вступают в действие, если модуль не включен в класс. Методы экземпляра в классе требуют, чтобы был экземпляр класса. Вы, вероятно, хотите метод класса вместо этого. И сам файл должен быть загружен, как правило, с помощью оператора require.

Если следующий код находится в файле getip.rb,

require 'socket'

class GetIP
  def self.local_ip
    orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true

    UDPSocket.open do |s|
      s.connect '64.233.187.99', 1
      s.addr.last
    end
  ensure
    Socket.do_not_reverse_lookup = orig
  end
end

Тогда вы сможете запустить его, сказав,

require 'getip'
GetIP.local_ip
0 голосов
/ 05 сентября 2008

require и include - это две разные вещи.

require - строго загрузить файл один раз из пути загрузки. Loadpath - это строка, и это ключ, который используется для определения, загружен ли файл уже.

include используется для "смешивания" модулей с другими классами. include вызывается для модуля, а методы модуля включаются в качестве методов экземпляра в классе.

  module MixInMethods
    def mixed_in_method
      "I'm a part of #{self.class}"
    end
  end

  class SampleClass
    include MixInMethods
  end

  mixin_class = SampleClass.new
  puts my_class.mixed_in_method # >> I'm a part of SampleClass

Но часто модуль, который вы хотите добавить, находится не в том же файле, что и целевой класс. Итак, вы делаете require 'module_file_name', а затем внутри класса вы делаете include module.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...