Используйте класс как метод - PullRequest
5 голосов
/ 14 марта 2019

Мне нравится, как вы создаете экземпляр объекта URI, используя имя класса URI:

uri = URI('https://www.example.com')

Очень аккуратно и просто.Как вы это делаете?

Например, предположим, у меня есть модуль:

module MyModule
   def self.mymethod()
   end
end

MyModule.mymethod - единственный метод в модуле.Раздражает, что каждый раз, когда я хочу, чтобы этот метод мне приходилось вводить:

MyModule.mymethod()

Он работает, но кажется избыточным ... это единственный метод в модуле.Есть ли способ вызвать только MyModule?

MyModule.mymethod()

Ответы [ 3 ]

5 голосов
/ 14 марта 2019

Если вы внимательно посмотрите на источник, вы найдете это :

module Kernel

  #
  # Returns +uri+ converted to an URI object.
  #
  def URI(uri)
    # ...
  end
  module_function :URI
end

Возможно, вас разочаровывает, но если вы сделаете URI('https://www.example.com'), вы просто вызовете метод, унаследованный отядро.

2 голосов
/ 14 марта 2019

В вашем примере URI - это просто метод с именем URI.Как показывает idmean в своем ответе, он определен как module_function в ядре, что делает его доступным везде, и, вероятно, есть веские причины делать это таким образом, но просто определяя его как нормальный метод восновная область действия будет в основном выполнять то же самое:

def MyModule
  puts "Called MyModule"
end

MyModule()
# => Called MyModule

См. это в действии на repl.it: https://repl.it/@jrunning/SnowHauntingLevels

0 голосов
/ 14 марта 2019

Если бы вы согласились на скобки, а не круглые скобки, вы могли бы сделать следующее.

class Module
  def [](*args, &block)
    public_send(methods.first, *args, &block)
  end
end

module A
  def self.a
    "Called A"
  end
end

A[]
  #=> "Called A"

module B
  def self.b(n)
    yield(n)
  end
end

B[9] { |n| "Cats have #{n} lives." }
  #=> "Cats have 9 lives."
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...