Я могу вызвать метод экземпляра для модуля Ruby без включения его?

170
задан Nakilon 11 September 2014 в 16:06
поделиться

6 ответов

Если метод на модуле превращен в функцию модуля, можно просто отозвать его Модификаций, как будто он был объявлен как

module Mods
  def self.foo
     puts "Mods.foo(self)"
  end
end

, подход module_function ниже постарается не повреждать любые классы, которые включают все Модификации.

module Mods
  def foo
    puts "Mods.foo"
  end
end

class Includer
  include Mods
end

Includer.new.foo

Mods.module_eval do
  module_function(:foo)
  public :foo
end

Includer.new.foo # this would break without public :foo above

class Thing
  def bar
    Mods.foo
  end
end

Thing.new.bar  

Однако мне любопытно, почему ряд несвязанных функций все содержится в том же модуле во-первых?

Отредактированный для показа это включает все еще работу, если public :foo назван после module_function :foo

130
ответ дан 2 revs 23 November 2019 в 20:47
поделиться

Другой способ сделать он, если Вы "владеете" модулем, должен использовать module_function.

module UsefulThings
  def a
    puts "aaay"
  end
  module_function :a

  def b
    puts "beee"
  end
end

def test
  UsefulThings.a
  UsefulThings.b # Fails!  Not a module method
end

test
78
ответ дан Arturo Herrero 23 November 2019 в 20:47
поделиться

Если Вы хотите назвать эти методы без включения модуля в другом классе тогда, необходимо определить их как методы модуля:

module UsefulThings
  def self.get_file; ...
  def self.delete_file; ...

  def self.format_text(x); ...
end

и затем можно назвать их с

UsefulThings.format_text("xxx")

или

UsefulThings::format_text("xxx")

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

18
ответ дан Raimonds Simanovskis 23 November 2019 в 20:47
поделиться

Во-первых, я рекомендовал бы разбить модуль в полезные вещи, в которых Вы нуждаетесь. Но можно всегда создавать класс, расширяющий это для вызова:

module UsefulThings
  def a
    puts "aaay"
  end
  def b
    puts "beee"
  end
end

def test
  ob = Class.new.send(:include, UsefulThings).new
  ob.a
end

test
6
ответ дан Dustin 23 November 2019 в 20:47
поделиться

Не уверенный, если кому-то все еще нужен он после 10 лет, но я решил его с помощью eigenclass.

module UsefulThings
  def useful_thing_1
    "thing_1"
  end

  class << self
    include UsefulThings
  end
end

class A
  include UsefulThings
end

class B
  extend UsefulThings
end

UsefulThings.useful_thing_1 # => "thing_1"
A.new.useful_thing_1 # => "thing_1"
B.useful_thing_1 # => "thing_1"
1
ответ дан 23 November 2019 в 20:47
поделиться

I think the shortest way to do just throw-away single call (without altering existing modules or creating new ones) would be as follows:

Class.new.extend(UsefulThings).get_file
139
ответ дан 23 November 2019 в 20:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: