我有以下工作正常。
app.rb
require "thor"
class App < Thor
desc "list_recipes [KEYWORD] [OPTIONS]", "List all recipes. If a keyword is given, it filters the list based off it."
option :format
option :show_time, type: :boolean, default: true #--show-time --no-show-time
def list_recipes keyword=nil
recipes = [
{
title: "Ratatouille",
cooking_time: "60 min",
ingredients: %w(potatoes carrots peppers onions zucchini tomatoes)
},
{
title: "Mac & Cheese",
cooking_time: "20 min",
ingredients: %w(macarroni cheese mustard milk)
},
{
title: "Caesar Salad",
cooking_time: "10 min",
ingredients: %w(chicken lettuce croutons eggs)
}
]
recipes_to_be_listed = if keyword.nil? then recipes
else recipes.select { |recipe| recipe[:title].downcase.include? keyword.downcase}
end
recipes_to_be_listed.each do | recipe |
if options[:format].nil?
print_default recipe
else options[:format] == "oneline"
print_oneline recipe
end
end
end
private
def print_default recipe
puts "-------------"
puts "Recipe: #{recipe[:title]}"
puts "It takes: #{recipe[:cooking_time]} to cook."
puts "The ingredients are: #{recipe[:ingredients].join(", ")}"
puts ""
end
def print_oneline recipe
if options[:show_time]
time = "(#{recipe[:cooking_time]})"
else
time = ""
end
puts %Q{#{recipe[:title]} #{time}}
end
end
App.start ARGV
# ARGV is for options, arguments, subcommand to be parsed in app.
现在我想通过阅读此文件来替换食谱。
recipes.txt
[
{
title: "Ratatouille",
cooking_time: "60 min",
ingredients: %w(potatoes carrots peppers onions zucchini tomatoes)
},
{
title: "Mac & Cheese",
cooking_time: "20 min",
ingredients: %w(macarroni cheese mustard milk)
},
{
title: "Caesar Salad",
cooking_time: "10 min",
ingredients: %w(chicken lettuce croutons eggs)
}
]
然后我尝试了以下但是它出错了。
def list_recipes keyword=nil
recipes = File.read('./recipes.txt')
..
读取包含数组并使用它的文件的最佳方法是什么?
答案 0 :(得分:0)
您可以尝试将该文件作为字符串加载,然后使用eval对其进行评估。但想想安全性!
array = eval(File.read('recipes.txt'))
也许最好将Marshal形式化为文件或做一些Factory类来创建它。
或者您可以将此结构隐藏到另一个文件中的常量中,只需要该文件即可访问该常量。
答案 1 :(得分:0)
您已经在使用结构化的文本文件,因此您也可以一直使用。
recipe.txt可能如下所示:
@recipes =
[
{
title: "Ratatouille",
cooking_time: "60 min",
ingredients: %w(potatoes carrots peppers onions zucchini tomatoes)
},
{
title: "Mac & Cheese",
cooking_time: "20 min",
ingredients: %w(macarroni cheese mustard milk)
},
{
title: "Caesar Salad",
cooking_time: "10 min",
ingredients: %w(chicken lettuce croutons eggs)
}
]
您的代码可能如下所示:
load './recipe.txt'
您将能够访问该实例变量。
所以,如果你打算使用结构化文件,你也可以使用Ruby。直到你需要使用某种编组工具(例如YAML或其他任何东西)的某些“优势”,你真的不需要它。
以下是我用来确保代码的IRB会话:
>> load 'recipe.txt'
=> true
>> @recipe
=> nil
>> @recipes
=> [{:title=>"Ratatouille", :cooking_time=>"60 min", :ingredients=>["potatoes"
, "carrots", "peppers", "onions", "zucchini", "tomatoes"]}, {:title=>"Mac & Ch
eese", :cooking_time=>"20 min", :ingredients=>["macarroni", "cheese", "mustard
", "milk"]}, {:title=>"Caesar Salad", :cooking_time=>"10 min", :ingredients=>[
"chicken", "lettuce", "croutons", "eggs"]}]
load
可行,require
的工作方式不同,因此无法使用此解决方案。
如此test.rb
文件所示:
load './recipe.txt'
puts @recipes
# >> {:title=>"Ratatouille", :cooking_time=>"60 min", :ingredients=>["potatoes", "carrots", "peppers", "onions", "zucchini", "tomatoes"]}
# >> {:title=>"Mac & Cheese", :cooking_time=>"20 min", :ingredients=>["macarroni", "cheese", "mustard", "milk"]}
# >> {:title=>"Caesar Salad", :cooking_time=>"10 min", :ingredients=>["chicken", "lettuce", "croutons", "eggs"]}
答案 2 :(得分:0)
不要将数据保存为Ruby文件。重用它要困难得多,再加上它会在代码中打开潜在的漏洞,如果恶意用户获得了对文件系统的访问权,就可以利用这些漏洞。
相反,使用YAML或JSON之类的方法来序列化数据,同时使其可以被其他语言重用。
以下是数据:
data = [
{
title: "Ratatouille",
cooking_time: "60 min",
ingredients: %w(potatoes carrots peppers onions zucchini tomatoes)
},
{
title: "Mac & Cheese",
cooking_time: "20 min",
ingredients: %w(macarroni cheese mustard milk)
},
{
title: "Caesar Salad",
cooking_time: "10 min",
ingredients: %w(chicken lettuce croutons eggs)
}
]
以下是YAML的外观:
require 'yaml'
puts data.to_yaml
# >> ---
# >> - :title: Ratatouille
# >> :cooking_time: 60 min
# >> :ingredients:
# >> - potatoes
# >> - carrots
# >> - peppers
# >> - onions
# >> - zucchini
# >> - tomatoes
# >> - :title: Mac & Cheese
# >> :cooking_time: 20 min
# >> :ingredients:
# >> - macarroni
# >> - cheese
# >> - mustard
# >> - milk
# >> - :title: Caesar Salad
# >> :cooking_time: 10 min
# >> :ingredients:
# >> - chicken
# >> - lettuce
# >> - croutons
# >> - eggs
请注意,它易于阅读,并可使用以下方式轻松检索:
data = YAML.load_file('path/to/the/data.yaml')
使用以下内容轻松编写:
File.write('path/to/the/data.yaml', data.to_yaml)
您也可以使用JSON,但YAML往往更容易阅读:
require 'json'
# >> [{"title":"Ratatouille","cooking_time":"60 min","ingredients":["potatoes","carrots","peppers","onions","zucchini","tomatoes"]},{"title":"Mac & Cheese","cooking_time":"20 min","ingredients":["macarroni","cheese","mustard","milk"]},{"title":"Caesar Salad","cooking_time":"10 min","ingredients":["chicken","lettuce","croutons","eggs"]}]
这是相同的JSON“美化”:
puts JSON.pretty_generate(data)
# >> [
# >> {
# >> "title": "Ratatouille",
# >> "cooking_time": "60 min",
# >> "ingredients": [
# >> "potatoes",
# >> "carrots",
# >> "peppers",
# >> "onions",
# >> "zucchini",
# >> "tomatoes"
# >> ]
# >> },
# >> {
# >> "title": "Mac & Cheese",
# >> "cooking_time": "20 min",
# >> "ingredients": [
# >> "macarroni",
# >> "cheese",
# >> "mustard",
# >> "milk"
# >> ]
# >> },
# >> {
# >> "title": "Caesar Salad",
# >> "cooking_time": "10 min",
# >> "ingredients": [
# >> "chicken",
# >> "lettuce",
# >> "croutons",
# >> "eggs"
# >> ]
# >> }
# >> ]
也可以使用以下内容轻松读取和解析JSON:
data = JSON[File.read('path/to/data.json')]
与YAML一样,JSON也很容易写入磁盘:
File.write('path/to/data.json', data.to_json)
在工作中,我们使用YAML来存储磁盘上的数据,使用JSON来获取我们在应用之间移动的数据;我们发现手动更容易阅读和修改YAML,并且JSON在整个线路上更有效。