gpt4 book ai didi

ruby-on-rails - 在 lib 目录的模块中使用类 - Rails 3

转载 作者:行者123 更新时间:2023-12-03 17:34:02 25 4
gpt4 key购买 nike

我在 lib 目录中有一个设置,如下所示:

lib/
copy_process.rb
copy_process/
processor.rb

copy_process.rb 和 processor.rb 包含模块定义 CopyProcess。 copy_process.rb 也定义了 CopyFile 类:

module CopyProcess
class CopyFile
end
end

processor.rb 的结构如下:

module CopyProcess
class Processer

end
end

在其中一个方法中,它创建了一个新的复制文件对象:

def append_file_if_valid(file_contents, headers, files, file_name)
unless headers
raise "Headers not found"
else
files << CopyProcess::CopyFile.new()
end
end

当我将这些文件用作命令行 ruby​​ 程序的一部分时,它运行良好。但是,我开始将它放入 Rails 应用程序中,并且我编写了 Cucumber/capybara 测试来点击按钮等使用它的地方。我从我的一个 AR 模型中初始化一个 Processor 对象,并多次调用上述方法。它似乎找不到 CopyFile 类,即使我的 application.rb 中有以下代码

config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]

有什么想法吗?

============================================= ================

编辑 上面的问题是通过将复制文件类提取到它自己的 lib 文件中来解决的。我现在有另一个问题:

CopyFile 类引用位于 lib/copy_process.rb 中的模块级辅助方法,如下所示:

module CopyProcess
# Gets the index of a value inside an array of the given array
def get_inner_index(value, arr)
idx = nil
arr.each_with_index do |e, i|
if e[0] == value
idx = i
end
end
return idx
end

def includes_inner?(value, arr)
bool = false
arr.each { |e| bool = true if e[0] == value }
return bool
end


# Encloses the string in double quotes, in case it contains a comma
# @param [String] - the string to enclose
# @return [String]
def enclose(string)
string = string.gsub(/\u2019/, '&rsquo;')
if string.index(',')
return "\"#{string}\""
else
return string
end
end
end

当我运行我的 cucumber 测试时,出现以下错误:

 undefined method `includes_inner?' for CopyProcess:Module (NoMethodError)
./lib/copy_process/copy_file.rb:64:in `set_element_name_and_counter'

这里指的是这个方法:

def set_element_name_and_counter(element_names, name)
if !CopyProcess::includes_inner?(name, element_names)
element_names << [name, 1]
else
# if it's in the array already, find it and increment the counter
current_element = element_names[CopyProcess::get_inner_index(name, element_names)]
element_names[CopyProcess::get_inner_index(name, element_names)] = [current_element[0], current_element[1]+1]
end
element_names
end

我还尝试将 lib/copy_process/目录中的 copy_file.rb 和其他文件向上移动到 lib 目录中。然后我收到以下错误:

 Expected /Users/aaronmcleod/Documents/work/copy_process/lib/copy_file.rb to define CopyFile (LoadError)
./lib/processor.rb:48:in `append_file_if_valid'

错误声明的行创建了一个 CopyFile 实例。我猜 rails 不喜欢以这种方式加载文件,对于以前的设置,我认为 copy_file.rb 在加载模块的其余部分时遇到问题。我试过要求它等等,但没有运气。您还可以在这里找到我最近的代码:https://github.com/agmcleod/Copy-Process/tree/rails

最佳答案

首先 config.autoload_paths += %W(#{config.root}/lib) 应该足够了。这会告诉 Rails 开始在/lib 中寻找结构正确的文件。

其次,我认为您遇到了问题,因为 CopyFile 不是 Rails 期望的位置。据我所知,您的设置“应该”有效,但您是否尝试过将 CopyFile 分离到 copy_process 文件夹下的自己的文件中?我的猜测是,因为 copy_process 文件夹存在,所以它期望所有 CopyProcess::* 类都在那里定义,而不是 copy_process.rb。

编辑:您可以考虑打开另一个问题,但问题的后半部分完全是一个不同的问题。

您可以像这样在模块中定义方法,

module X
def method_one
puts "hi"
end
end

这种形式的方法是模块上的实例方法,它们有非常特殊的限制。例如,您不能从模块定义之外访问它们(我怀疑它们以前是如何工作的)。执行上面给出

> X::method_one
NoMethodError: undefined method `method_one' for X:Module

如果您想从其他范围访问这些方法,您有几个选择。

使用类方法

 module X
def self.method_one
puts "hi"
end
end
X::hi #=> "hi"

使用Mixins

module X
module Helpers
def method_one
puts "hi"
end
end
end

class CopyFile
include X::Helpers

def some_method
method_one #=> "hi"
self.method_one #=> "hi"
end
end

关于ruby-on-rails - 在 lib 目录的模块中使用类 - Rails 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6930018/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com