我正在尝试解决实验室,但我不确定发生了什么。我要做的是我必须从目录导入一些文件名(.mp3' s)然后使用文件名来制作一些对象。我仍然坚持从目录中获取文件名。测试要求我
"将文件名规范化为仅没有路径的mp3文件名"
测试如下:
it 'normalizes the filename to just the mp3 filename with no path' do
test_music_path = "./spec/fixtures/mp3s"
music_importer = MP3Importer.new(test_music_path)
expect(music_importer.files).to include("Action Bronson - Larry Csonka - indie.mp3")
expect(music_importer.files).to include("Real Estate - Green Aisles - country.mp3")
expect(music_importer.files).to include("Real Estate - It's Real - hip-hop.mp3")
expect(music_importer.files).to include("Thundercat - For Love I Come - dance.mp3")
end
我的代码是:
class MP3Importer
attr_accessor :path
def initialize(path)
@path = path
end
def files
Dir.chdir(@path)
filename = Dir.glob("*.mp3")
filename
end
end
这也是通过这两个测试:
describe '#initialize' do
it 'accepts a file path to parse mp3 files from' do
test_music_path = "./spec/fixtures/mp3s"
music_importer = MP3Importer.new(test_music_path)
expect(music_importer.path).to eq(test_music_path)
end
describe '#files' do
it 'loads all the mp3 files in the path directory' do
test_music_path = "./spec/fixtures/mp3s"
music_importer = MP3Importer.new(test_music_path)
expect(music_importer.files.size).to eq(4)
end
但它产生的错误是:
Failure/Error: expect(music_importer.files).to include("Action Brons
Errno::ENOENT:
No such file or directory @ dir_chdir - ./spec/fixtures/mp3s
老实说我不知道将文件名规范化为mp3文件名没有路径意味着什么?这是非常误导的。我的#files方法中已经有变量filename的文件名数组。
我的问题是:
答案 0 :(得分:1)
初步说明:发布所有代码并且只发布最少的代码,以便我们可以复制粘贴并执行它来重现错误。在这种情况下,RSpec标签和RSpec的版本也很有用。
当我执行你的代码时:
No such file or directory @ dir_chdir - ./spec/fixtures/mp3s
# ./lib/t_a.rb:14:in `chdir'
错误发生在第14行的声明中:
Dir.chdir(@path)
这给出了chdir
在当前工作目录中找不到所请求的子目录的线索。为什么?添加跟踪以显示当前工作目录:
def files
puts "in files, path=#{@path}"
puts "wd=...#{Dir.getwd.sub(/.*ruby(.*)/, '\1')}"
current_dir = Dir.getwd
Dir.chdir(@path)
...
并运行测试(我在...devl/ruby/zintlist/mp3_importer
工作):
$ rspec
MP3Importer
#initialize
accepts a file path to parse mp3 files from
#files
in files, path=./spec/fixtures/mp3s
wd=.../zintlist/mp3_importer
loads all the mp3 files in the path directory
#xxxx
in files, path=./spec/fixtures/mp3s
wd=.../zintlist/mp3_importer/spec/fixtures/mp3s
你看到了不同之处:
wd=.../zintlist/mp3_importer
wd=.../zintlist/mp3_importer/spec/fixtures/mp3s
执行files
时,会产生副作用:当前目录已更改。在files
的第二次执行中,Dir.chdir
开始在第一次执行所留下的当前目录中搜索,即.../mp3_importer/spec/fixtures/mp3s
,而mp3s
当然不包含{{1}因此错误./spec/fixtures/mp3s
。
解决方案是恢复输入方法时当前的目录:
No such file or directory
然后跟踪显示它已经恢复:
def files
puts "in files, path=#{@path}"
puts "wd=...#{Dir.getwd.sub(/.*ruby(.*)/, '\1')}"
current_dir = Dir.getwd
Dir.chdir(@path)
filenames = Dir.glob("*.mp3")
Dir.chdir(current_dir)
filenames
end
您可能已经知道,如果您在wd=.../zintlist/mp3_importer
...
wd=.../zintlist/mp3_importer
块内处理文件,则在块退出时文件将关闭。这同样适用于恢复当前目录。来自The Pickaxe Dir.chdir:
如果给出了一个块,则传递新当前的名称 目录,并以此作为当前执行块 目录。块时恢复原始工作目录 退出。
鉴于这些文件:
File.open ... do ... end
#file t.rb
class MP3Importer
attr_accessor :path
def initialize(path)
@path = path
end
def files
# puts "in files, path=#{@path}"
# puts "wd=#{Dir.getwd.sub(/.*ruby(.*)/, '\1')}"
filenames = Dir.chdir(@path) do | path |
# puts path
Dir.glob("*.mp3")
end
puts "names=#{filenames}"
filenames
end
end
执行:
# file t_spec.rb
require 't'
RSpec.describe MP3Importer do
let(:test_music_path) { "./spec/fixtures/mp3s" }
let(:music_importer) { MP3Importer.new(test_music_path) }
describe '#initialize' do
it 'accepts a file path to parse mp3 files from' do
expect(music_importer.path).to eq(test_music_path)
end
end
describe '#files' do
it 'loads all the mp3 files in the path directory' do
expect(music_importer.files.size).to eq(4)
end
end
describe '#xxxx' do
it 'normalizes the filename to just the mp3 filename with no path' do
expect(music_importer.files).to include('f4.mp3')
end
end
end
所有测试均为绿色。
由于方法返回值是上次执行的表达式的值,您可以像这样简化$ ruby -v
ruby 2.4.0rc1 (2016-12-12 trunk 57064) [x86_64-darwin15]
$ rspec -v
RSpec 3.6.0.beta2
- rspec-core 3.6.0.beta2
- rspec-expectations 3.6.0.beta2
- rspec-mocks 3.6.0.beta2
- rspec-support 3.6.0.beta2
$ rspec
MP3Importer
#initialize
accepts a file path to parse mp3 files from
#files
names=["f1.mp3", "f2.mp3", "f3.mp3", "f4.mp3"]
loads all the mp3 files in the path directory
#xxxx
names=["f1.mp3", "f2.mp3", "f3.mp3", "f4.mp3"]
normalizes the filename to just the mp3 filename with no path
Finished in 0.00315 seconds (files took 0.09868 seconds to load)
3 examples, 0 failures
:
files
声明"标准化......是什么意思?
我不知道。我想它只收集名称与某个模式相对应的文件,def files
Dir.chdir(@path) do | path |
Dir.glob("*.mp3")
end
end
。
我可以说RDoc从命令行获取输入文件名,并将它们传递给名为*.mp3
的例程:
normalized_file_list