ошибки ruby mixins

#ruby #mixins

#ruby #mixins

Вопрос:

Меня смущает следующий фрагмент кода.

В библиотеке HTTParty есть метод класса с именем def self.get(..) .

Я включаю его в Client модуль, а затем включаю этот Client модуль в свой Line класс и получаю доступ к get методу в моем def self.hi() методе. Но когда я запускаю, он выдает ошибку:

 ruby geek-module.rb
geek-module.rb:12:in `hi': undefined method `get' for Line:Class (NoMethodError)
  from geek-module.rb:16:in `<main>'
  

Почему я не могу получить доступ к этому get методу HTTParty?
Ниже приведен код:

 require 'rubygems'
require 'httparty'

module Client
  include HTTParty
end

class Line
  include Client

  def self.hi
    get("http://gogle.com")
  end
end

puts Line.hi
  

Ответ №1:

Вы не можете получить доступ к методу self.get, потому что вы используете include HTTParty , include делает методы доступными экземплярам класса, а не самому классу, ваш hi метод является методом класса, но get метод является методом экземпляра. Если вы используете что-то вроде:

 class Line
 include Client

 def hi
   get("http://gogle.com")
 end 
end

line = Line.new
line.get
  

Я думаю, что это должно сработать

… или просто используйте extend Client вместо include

Комментарии:

1. Выделите код, поместив его в обратные метки «, а не выделив жирным шрифтом.

2. Это не тот случай. Если вы видите источник HTTParty, то это просто синтаксический сахар, который нужно использовать include вместо extend . т.е. get это метод класса. Он расширен методом ruby hook def included(base) и внутри блока просто расширяется base.extend .

Ответ №2:

Итак, когда вы include HTTParty находитесь в Client модуле, вы можете получить доступ к get методу через Client.get . И когда вы включаете Client в Line класс, вы также можете получить доступ к get методу через Client.get . На самом деле, если вы хотите использовать get метод в своем классе Line, вам не нужно его включать. Итак:

 require 'rubygems'
require 'httparty'

module Client
  include HTTParty
end

class Line

  def self.hi
    Client.get("http://google.com")
  end
end

puts Line.hi
  

или, если вам нужен get метод в вашем Line классе, вы можете использовать что-то вроде этого:

 class Client
  include HTTParty
end

class Line < Client
  def self.hi
    get("http://google.com")
  end
end

puts Line.hi
  

Комментарии:

1. Спасибо за ответ. Но как добиться этого без наследования, используя только mixins?

2. Я думаю, вы не можете. Почему вы не можете использовать Client.get ?

3. Я могу использовать Client.get , но я хотел бы знать причину, по которой простое использование get не работает?