#ruby #loops #oop #dependency-injection
#ruby #циклы #ооп #внедрение зависимостей
Вопрос:
Я столкнулся с некоторыми препятствиями, когда попытался внедрить зависимость внутри этого кода, цель состоит в том, чтобы передать объект функции, вводящей зависимость. Я пробовал это с помощью procs, но это не имеет никакого смысла, поскольку proc parser = Proc.new { Parser.new }
вызвал новый объект, но аргументы, переданные после инициализации, я не пробовал лямбды и чувствую, что полностью заблудился, найдя способ, который не нарушает стиль Ruby. Пожалуйста, помогите мне.
Вот код:
class Interface
attr_reader :data, :parser
def initialize(data = [1, 2, 3], parser = Parser.new)
@data = data
@parser = parser
end
def parse_fresh_reports
data.each do |datum|
parser.new(datum).run
end
end
end
class Parser
attr_accessor :datum
def initialize(datum)
@datum = datum
end
def parse_report
puts "from #{self.inspect} #{datum}"
end
end
Interface.new.parse_fresh_reports
Я хочу что-то вроде этого
class Interface
attr_accessor :data, :parser
def initialize(data = [1, 2, 3], parser = Parser)
@data = data
@parser = parser
end
def parse_fresh_reports
data.each do |datum|
parser.run(datum)
end
end
end
class Parser
attr_accessor :datum
def self.run(datum)
set_params(datum)
parse_report
end
def set_params(datum)
@datum = datum
end
def parse_report
puts "from #{self.inspect} #{datum}"
end
end
Interface.new.parse_fresh_reports
Я не знаю, можно ли передавать const в качестве аргумента.
Ответ №1:
parser = Parser.new
не работает, потому Parser.new
что требуется аргумент.
Вы можете передать константу, она передаст содержимое этой константы. В данном случае класс синтаксического анализатора. Это объект класса. Но то, как вы написали класс синтаксического анализатора, смешивает методы класса, например self.run
, с методами экземпляра, такими как set_params
. Чтобы заставить его работать, вам нужно было бы сделать все методом класса.
class Parser
# Everything inside the following block affects the class Parser.
# Not instances of Parser.
class << self
attr_accessor :datum
def run(datum)
set_params(datum)
parse_report
end
def set_params(datum)
@datum = datum
end
def parse_report
puts "from #{self.inspect} #{datum}"
end
end
end
Однако это означает, что одновременно может выполняться только один синтаксический анализ.
Вместо этого передайте новый объект синтаксического анализатора, а затем передайте ему его данные. Его можно передать прямо run
.
class Interface
attr_reader :data, :parser
def initialize(data = [1, 2, 3], parser = Parser.new)
@data = data
@parser = parser
end
def parse_fresh_reports
data.each do |datum|
# Pass the datum directly to each run.
parser.run(datum)
end
end
end
class Parser
def run(datum)
puts "from #{inspect} #{datum}"
end
end
Interface.new.parse_fresh_reports
Это позволяет передавать другие синтаксические анализаторы.
class MyParser < Parser
def run(*)
super
puts "Me, too!"
end
end
Interface.new([1, 2, 3], MyParser.new).parse_fresh_reports