#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 hookdef 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
не работает?