如何将文件名规范化为没有路径的 mp3 文件名? Ruby
How to normalise the filename to just the mp3 filename with no path ? Ruby
我正在尝试解决实验室问题,但我不确定发生了什么。我必须做的是,我必须从目录中导入一些文件名(.mp3),然后使用文件名制作一些对象。我仍然坚持从目录中获取文件名。测试要求我
"Normalise the filename to just the mp3 filename with no path"
测试如下:
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 方法中的变量文件名中已经有了文件名数组。
我的问题是:
- 语句 "Normalise the filename to just the mp3 filename with no path" 是什么意思?测试要我做什么?
- 发布的代码中发生了什么?
- 为什么错误指向目录?当目录确实有所需的文件时?
初步说明:post所有代码,只有最少的代码,以便我们可以复制粘贴并执行它来重现错误。 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(.*)/, '')}"
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
当然不包含[=29] =],因此错误 No such file or directory
.
解决方法是恢复进入方法时的当前目录:
def files
puts "in files, path=#{@path}"
puts "wd=...#{Dir.getwd.sub(/.*ruby(.*)/, '')}"
current_dir = Dir.getwd
Dir.chdir(@path)
filenames = Dir.glob("*.mp3")
Dir.chdir(current_dir)
filenames
end
然后trace显示已经恢复:
wd=.../zintlist/mp3_importer
...
wd=.../zintlist/mp3_importer
您可能已经知道,如果您在 File.open ... do ... end
块内处理文件,则该文件会在块退出时关闭。这同样适用于恢复当前目录。来自 The Pickaxe Dir.chdir :
If a block is given, it is passed the name of the new current
directory, and the block is executed with that as the current
directory. The original working directory is restored when the block
exits.
鉴于这些文件:
#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(.*)/, '')}"
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
所有测试都是绿色的。
因为方法 return 的值是最后执行的表达式的值,你可以像这样简化 files
:
def files
Dir.chdir(@path) do | path |
Dir.glob("*.mp3")
end
end
What does the statement "Normalise ... mean ?
我不知道。我想它只收集名称对应于特定模式的文件,这里 *.mp3
.
我能说的是 RDoc 从命令行获取输入文件名并将它们传递给名为 normalized_file_list
:
的例程
# file rdoc.rb
##
# Given a list of files and directories, create a list of all the Ruby
# files they contain.
#
# If +force_doc+ is true we always add the given files, if false, only
# add files that we guarantee we can parse. It is true when looking at
# files given on the command line, false when recursing through
# subdirectories.
#
# The effect of this is that if you want a file with a non-standard
# extension parsed, you must name it explicitly.
def normalized_file_list(relative_files, force_doc = false,
exclude_pattern = nil)
file_list = []
relative_files.each do |rel_file_name|
next if rel_file_name.end_with? 'created.rid'
next if exclude_pattern && exclude_pattern =~ rel_file_name
stat = File.stat rel_file_name rescue next
case type = stat.ftype
when "file" then
next if last_modified = @last_modified[rel_file_name] and
stat.mtime.to_i <= last_modified.to_i
if force_doc or RDoc::Parser.can_parse(rel_file_name) then
file_list << rel_file_name.sub(/^\.\//, '')
@last_modified[rel_file_name] = stat.mtime
end
when "directory" then
next if rel_file_name == "CVS" || rel_file_name == ".svn"
created_rid = File.join rel_file_name, "created.rid"
next if File.file? created_rid
dot_doc = File.join rel_file_name, RDoc::DOT_DOC_FILENAME
if File.file? dot_doc then
file_list << parse_dot_doc_file(rel_file_name, dot_doc)
else
file_list << list_files_in_directory(rel_file_name)
end
else
warn "rdoc can't parse the #{type} #{rel_file_name}"
end
end
file_list.flatten
end
##
# Return a list of the files to be processed in a directory. We know that
# this directory doesn't have a .document file, so we're looking for real
# files. However we may well contain subdirectories which must be tested
# for .document files.
def list_files_in_directory dir
files = Dir.glob File.join(dir, "*")
normalized_file_list files, false, @options.exclude
end
我正在尝试解决实验室问题,但我不确定发生了什么。我必须做的是,我必须从目录中导入一些文件名(.mp3),然后使用文件名制作一些对象。我仍然坚持从目录中获取文件名。测试要求我
"Normalise the filename to just the mp3 filename with no path"
测试如下:
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 方法中的变量文件名中已经有了文件名数组。
我的问题是:
- 语句 "Normalise the filename to just the mp3 filename with no path" 是什么意思?测试要我做什么?
- 发布的代码中发生了什么?
- 为什么错误指向目录?当目录确实有所需的文件时?
初步说明:post所有代码,只有最少的代码,以便我们可以复制粘贴并执行它来重现错误。 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(.*)/, '')}"
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
当然不包含[=29] =],因此错误 No such file or directory
.
解决方法是恢复进入方法时的当前目录:
def files
puts "in files, path=#{@path}"
puts "wd=...#{Dir.getwd.sub(/.*ruby(.*)/, '')}"
current_dir = Dir.getwd
Dir.chdir(@path)
filenames = Dir.glob("*.mp3")
Dir.chdir(current_dir)
filenames
end
然后trace显示已经恢复:
wd=.../zintlist/mp3_importer
...
wd=.../zintlist/mp3_importer
您可能已经知道,如果您在 File.open ... do ... end
块内处理文件,则该文件会在块退出时关闭。这同样适用于恢复当前目录。来自 The Pickaxe Dir.chdir :
If a block is given, it is passed the name of the new current directory, and the block is executed with that as the current directory. The original working directory is restored when the block exits.
鉴于这些文件:
#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(.*)/, '')}"
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
所有测试都是绿色的。
因为方法 return 的值是最后执行的表达式的值,你可以像这样简化 files
:
def files
Dir.chdir(@path) do | path |
Dir.glob("*.mp3")
end
end
What does the statement "Normalise ... mean ?
我不知道。我想它只收集名称对应于特定模式的文件,这里 *.mp3
.
我能说的是 RDoc 从命令行获取输入文件名并将它们传递给名为 normalized_file_list
:
# file rdoc.rb
##
# Given a list of files and directories, create a list of all the Ruby
# files they contain.
#
# If +force_doc+ is true we always add the given files, if false, only
# add files that we guarantee we can parse. It is true when looking at
# files given on the command line, false when recursing through
# subdirectories.
#
# The effect of this is that if you want a file with a non-standard
# extension parsed, you must name it explicitly.
def normalized_file_list(relative_files, force_doc = false,
exclude_pattern = nil)
file_list = []
relative_files.each do |rel_file_name|
next if rel_file_name.end_with? 'created.rid'
next if exclude_pattern && exclude_pattern =~ rel_file_name
stat = File.stat rel_file_name rescue next
case type = stat.ftype
when "file" then
next if last_modified = @last_modified[rel_file_name] and
stat.mtime.to_i <= last_modified.to_i
if force_doc or RDoc::Parser.can_parse(rel_file_name) then
file_list << rel_file_name.sub(/^\.\//, '')
@last_modified[rel_file_name] = stat.mtime
end
when "directory" then
next if rel_file_name == "CVS" || rel_file_name == ".svn"
created_rid = File.join rel_file_name, "created.rid"
next if File.file? created_rid
dot_doc = File.join rel_file_name, RDoc::DOT_DOC_FILENAME
if File.file? dot_doc then
file_list << parse_dot_doc_file(rel_file_name, dot_doc)
else
file_list << list_files_in_directory(rel_file_name)
end
else
warn "rdoc can't parse the #{type} #{rel_file_name}"
end
end
file_list.flatten
end
##
# Return a list of the files to be processed in a directory. We know that
# this directory doesn't have a .document file, so we're looking for real
# files. However we may well contain subdirectories which must be tested
# for .document files.
def list_files_in_directory dir
files = Dir.glob File.join(dir, "*")
normalized_file_list files, false, @options.exclude
end