我有文件阅读程序。该程序读取.txt文件并运行一些函数。 我想通过文件名更改功能。 我的.txt文件有命名规则,如A001.txt,B001,C001 ......等等。 我正在使用if-else语句来改变函数。
def Function1(input)
if filename =~ /A.+\.txt/
some process....
elsif filename =~ /B.+\.txt/
some process....
.....
end
def Funcition2(input)
if filename =~ /A.+\.txt/
some process....
elsif filename =~ /B.+\.txt/
some process....
.....
end
我有更多类似的功能。 我认为这段代码效率低,可读性差。 阅读文件时更改功能的最佳方法是什么?
答案 0 :(得分:0)
你可以使用开关声明 - 大小写 - 为此。这是以前的答案:How to write a Ruby switch statement (case...when) with regex and backreferences?
基本上是这样的:
filenames.each do |filename|
case filename
when /A.+\.txt/
function 1
when /B.+\.txt/
function 2
else
function 3
end
end
答案 1 :(得分:0)
我喜欢使用动态方法调用来做这种事情:
def Function1(input)
prefix = filename[0].downcase
handler = "import_#{preview}_file"
handler = 'import_unknown_file' if !respond_to?(handler)
send(handler, input)
end
def import_a_file(input); end
def import_b_file(input); end
def import_unknown_file(input); end
您可以更进一步,使其更具可读性:
HANDLERS_FOR_PREFIXES = {
'a' => :import_account_file,
'b' => :import_balance_file,
'default' => :import_other_file
}
def Function1(input)
prefix = filename[0].downcase
handler = HANDLERS_FOR_PREFIXES[prefix] || HANDLERS_FOR_PREFIXES['default']
send(handler, input)
end
def import_account_file(input); end
但是,我怀疑您处理文件的顺序可能很重要(如果您要导入银行信息,则需要在将交易导入帐户之前导入帐户)。所以做一些像这样的事情可能是有道理的:
FILE_HANDLERS = {
'A*.txt' => :import_account_file,
'T*.txt' => :import_transaction_file
}
def Function1(input)
FILE_HANDLERS.each do |file_pattern, handler|
Dir.glob(file_pattern).each do |filename|
File.open(filename) do |f|
f.each_line do |line|
parsed_line = parse(parse)
send(handler, parsed_line);
end
end
end
end
end
虽然我会重构那个去除深层嵌套。
最后,随着代码变得越来越复杂,您可能希望将其分解为单独的类来处理每种类型的文件。这为您提供了很多重用和分解代码的机会。例如:
class AccountImporter < Importer
def initialize(input); end
def process
end
HANDLERS_FOR_PREFIXES = {
'a' => AccountImporter,
...
}
def Function1(input)
prefix = filename[0].downcase
handler = HANDLERS_FOR_PREFIXES[prefix] || HANDLERS_FOR_PREFIXES['default']
handler.new(input).process
end