我的spec_helper
看起来像这样:
require 'pry'
require 'helpers/data_helper.rb'
require 'distributer.rb'
require 'house_distributer.rb'
require 'accounting_service.rb'
require 'mixer_worker.rb'
require 'mixer.rb'
require 'transaction_service.rb'
ENV['RACK_ENV'] = 'test'
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.warnings = true
config.order = :random
end
和一个如下所示的文件夹结构:
.
├── Gemfile
├── Gemfile.lock
├── README.md
├── app.rb
├── config.ru
├── lib
│ ├── accounting_service.rb
│ ├── distributer.rb
│ ├── house_distributer.rb
│ ├── mixer.rb
│ ├── mixer_worker.rb
│ └── transaction_service.rb
├── public
│ ├── css
│ │ └── add_coins.css
│ ├── images
│ │ └── bitcoin_dawg.jpg
│ └── javascripts
│ └── add_coins.js
├── spec
│ ├── helpers
│ │ └── data_helper.rb
│ ├── lib
│ │ ├── accounting_service_spec.rb
│ │ └── transaction_service_spec.rb
│ └── spec_helper.rb
└── views
└── add_coins.erb
这不起作用:
Dir["lib/*.rb"].each {|file| require file }
[1] pry(main)> Dir["lib/*.rb"]
=> ["lib/house_distributer.rb", "lib/distributer.rb", "lib/mixer.rb", "lib/accounting_service.rb", "lib/mixer_worker.rb", "lib/transaction_service.rb"]
我收到此错误消息:
/Users/jwan/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- lib/house_distributer.rb (LoadError)
from /Users/jwan/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
我可以做些什么来使这更容易?
另外注意,distributer.rb
必须在house_distributer.rb
之前加载,因为:
class HouseDistributer < Distributer
end
答案 0 :(得分:4)
对最大辩护人答案的一些解释......
当你写:
require 'lib/house_distributer.rb'
ruby在分配给$LOAD_PATH
环境变量的目录中查找该文件。 $LOAD_PATH
是一个字符串数组,其中每个String都是目录的路径。将按顺序搜索$ LOAD_PATH数组中的目录,并且第一个匹配获胜。
如果$LOAD_PATH
包含名为:
'/Users/7stud/ruby_programs'
然后上面的require
语句将查找具有绝对路径的文件:
'/Users/7stud/ruby_programs/lib/house_distributer.rb'
您可以查看$LOAD_PATH
中的目录:
$ puts $LOAD_PATH
这就是我得到的:
/Users/7stud/.rvm/gems/ruby-2.4.0@global/gems/did_you_mean-1.1.0/lib
/Users/7stud/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby/2.4.0
/Users/7stud/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby/2.4.0/x86_64-darwin14
/Users/7stud/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby
/Users/7stud/.rvm/rubies/ruby-2.4.0/lib/ruby/vendor_ruby/2.4.0
/Users/7stud/.rvm/rubies/ruby-2.4.0/lib/ruby/vendor_ruby/2.4.0/x86_64-darwin14
/Users/7stud/.rvm/rubies/ruby-2.4.0/lib/ruby/vendor_ruby
/Users/7stud/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0
/Users/7stud/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/x86_64-darwin14
显然,你的应用程序的文件不在那些目录中。
另一方面,如果您require
文件的路径以/
或.
开头 - 例如:
require './lib/house_distributer.rb'
然后ruby跳过$LOAD_PATH
,在这种情况下,ruby会查找相对于当前工作目录的文件。但请注意,当前工作目录可能不是包含带有require语句的文件的目录。例如,如果从不同的目录执行sinatra程序,比如说包含require
语句的文件中的两个级别,则两个级别的目录将是当前工作目录,并且ruby将查找相对于两个级别向上目录所需的文件。
输入require_relative
。 require_relative
将查找相对于当前文件路径的文件 - 而不是当前工作目录。
因此,您可能永远不应将require
与相对路径一起使用,而应使用require_relative
。
请注意,您也可以在任何时候以编程方式将路径添加到$ LOAD_PATH:
$LOAD_PATH << '/Users/7stud/ruby_programs'
如果该目录中有一个名为dog.rb is
的文件,我可以这样要求:
require 'dog' #extension is unnecessary
对评论的回应:
最简单的事情是:
$LOAD_PATH << "/Users/jwan/Desktop/programming/interview_questions/gemini/jobcoin_mixer/"
但在sinatra中,settings.root
是您的app目录的路径,所以:
$LOAD_PATH.unshift setttings.root
通过这种方式,您可以将应用移动到另一个目录而无需进行任何更改。
或者,您可以从lib/
返回的每条路径的前面删除Dir[]
:
require 'pathname'
paths = [
"lib/house_distributer.rb",
"lib/distributer.rb",
"lib/mixer.rb",
"lib/accounting_service.rb",
]
new_paths = paths.map do |path|
pn = Pathname.new path
pn.relative_path_from(pn.parent).to_s
end
p new_paths
--output:--
["house_distributer.rb", "distributer.rb", "mixer.rb", "accounting_service.rb"]
答案 1 :(得分:2)
找不到文件是因为您使用的是defmodule MyApp.Guardian do
use Guardian, otp_app: :my_app
def subject_for_token(resource, _claims) do
sub = to_string(resource.id)
{:ok, sub}
end
def subject_for_token(_, _) do
{:error, :reason_for_error}
end
def resource_from_claims(claims) do
resource = %{id: 1}
{:ok, resource}
end
def resource_from_claims(_claims) do
{:error, :reason_for_error}
end
def after_encode_and_sign(resource, claims, token, _options) do
with {:ok, _} <- Guardian.DB.after_encode_and_sign(resource, claims["typ"], claims, token) do
{:ok, token}
else whatever ->
IO.inspect whatever
end
end
def on_verify(claims, token, _options) do
with {:ok, _} <- Guardian.DB.on_verify(claims, token) do
{:ok, claims}
end
end
def on_revoke(claims, token, _options) do
with {:ok, _} <- Guardian.DB.on_revoke(claims, token) do
{:ok, claims}
end
end
end
而不是"lib/*.rb"
。
要确保以正确的顺序加载依赖项,您可以执行以下操作:
将HouseDistributor移至./"lib/*.rb"
需要这样的文件:
lib/distributor/house_distributor.rb
这使用Dir['./lib/**/*.rb']
.sort_by { |path| path.count("/") }
.each { |path| require path }
进行递归搜索,并按照&#34; /&#34;的计数对文件进行排序。 (他们的深度)在要求
请注意,如果您正在执行递归需求,请记住您实际上确实需要所有这些文件。例如,如果您使用的是ActiveRecord并且有一个schema.rb文件,那么您可能并不想要这样做。
答案 2 :(得分:2)
其他2个答案在技术上是正确的并且解决目标而不是目标。换句话说 - 你为什么要这样做呢? 例如,为什么这样做:
另外注意,distributer.rb必须在house_distributer.rb之前加载,因为:
class HouseDistributer < Distributer
end
而不是这个?
require_relative "distributer.rb"
class HouseDistributer < Distributer
end
在测试中( cough )抱歉, specs :
# spec/house_distributer_spec.rb
require 'spec_helper'
require_relative "../lib/house_distributer.rb"
# spec/transaction_service_spec.rb
require 'spec_helper'
require_relative "../lib/transaction_service.rb"
由于transaction_service.rb
似乎需要来自HouseDistributer
的{{1}} ...
lib/house_distributer.rb
如果某个文件需要另一个文件运行,那么# lib/transaction_service.rb
require_relative "house_distributer.rb"
(或require
)就会在需要它的文件中运行。然后你得到:
require_relative
文件是否真的需要?)require
引入以来一直是一个可疑的需求)。require_relative
可能会破坏沙盒并使规格工作失败,方法是加载已安装在系统上的gem,但未在gemspec中定义为依赖项。< / LI>
我添加,也使用捆绑器的沙盒,以避免进一步的错误,让它处理你的负载路径,例如。
require
(或Mac上的vendor.noindex)然后:
bundle install --binstubs --path=vendor
以及你需要的任何命令行args。