通过定义哈希数组的方法进行重构
Refactor by defining method for Array of Hashes
我正在尝试通过定义条件方法来重构我的代码。
目前的代码功能完美,但我需要在保持现有结构和可读性的情况下彻底重构它。
在这种情况下,要求用户进行选择。该选择与散列数组中的符号相关联。该方法应替换下面此示例中的最后两个 puts
。代码一遍又一遍地打印这两行。
puts"Red, white, or something else?"
user_category_selection = gets.chomp.downcase
puts "-"*80
wine_rack = [
{ name: "The Fugitive",
vintage: 2010,
category: "Red",
grape_composition: "Red Blend",
location: "Napa, California",
personal_rating: 91},
{ name: "Au Bon Climat",
vintage: 2010,
category: "White",
grape_composition: "Chardonnay",
location: "Santa Barbara, California",
personal_rating: 89},
{ name: "Laurent-Perrier",
vintage: "Non-vintage",
category: "Something Else",
grape_composition: "Ultra Brut",
location: "France",
personal_rating: 92}
]
这是不起作用的部分:
def vintage_name_location(category)
category = wine_rack[:category].downcase
while category.downcase.include? user_category_selection
puts "#{wine[:vintage]} #{wine[:name]}, #{wine[:location]}".center(80)
puts "#{wine[:grape_composition]}, rated #{wine[:personal_rating]} points".center(80)
end
end
puts vintage_name_location(user_category_selection)
剩下的代码是:
until ["white", "red", "something else"].include? user_category_selection.downcase
puts "Pardon me for asking, but are you intoxicated already?".center(80)
puts "I said red, white, or something else.".center(80)
user_category_selection = gets.chomp
end
if user_category_selection.downcase.eql? "red"
puts "May I suggest one of these delightful reds:"
puts "--------------------------------------------------".center(80)
for wine in wine_rack
if wine[:category].downcase == user_category_selection
puts "#{wine[:vintage]} #{wine[:name]}, #{wine[:location]}".center(80)
puts "#{wine[:grape_composition]}, rated #{wine[:personal_rating]} points".center(80)
puts "--------------------------------------------------".center(80)
end
end
elsif user_category_selection.downcase.eql? "white"
正如您正确描述的那样,您的 wine_rack
是一个数组,因此您无法使用这样的类别名称查找项目:wine_rack[:category]
.
一种方法是使用 select
来挑选符合以下类别的葡萄酒:
matching_wines = wine_rack.select { |wine| wine[:category].downcase == category }
您可以像这样将其包装在您的函数中:
def wines_in_category(category)
wine_rack.select { |wine| wine[:category].downcase == category }
end
然后像这样使用它:
suitable_wines = wines_in_category(user_category_selection)
for wine in suitable_wines
...
这是另一个解决方案,指出了您必须使用哪些变量。
请注意,您无法直接从该方法与 wine_rack
进行交互。可以使用send
方法打开作用域门,也可以只传入wine_rack
数组
此外,Array#select
将 return 块 return 为真的所有实例。这现在可能不会影响您的软件,但以后可能会导致问题:
puts "Variables I have to work with: #{local_variables}"
def get_wine_information(passed_wine_rack,user_selection)
puts "Variables I have to work with inside method: #{local_variables}"
selection = passed_wine_rack.find {|wine| wine[:category] == user_selection}
puts "#{selection[:vintage]} #{selection[:name]}, #{selection[:location]}"
puts "#{selection[:grape_composition]}, rated #{selection[:personal_rating]} points"
end
#Scope Gate
Kernel.send(:define_method, :get_wine_info) do |user_selection|
puts "Variables I have to work with inside scope gate: #{local_variables}"
end
#Calling just to see scope information
get_wine_info("")
get_wine_information(wine_rack,user_category_selection)
我正在尝试通过定义条件方法来重构我的代码。
目前的代码功能完美,但我需要在保持现有结构和可读性的情况下彻底重构它。
在这种情况下,要求用户进行选择。该选择与散列数组中的符号相关联。该方法应替换下面此示例中的最后两个 puts
。代码一遍又一遍地打印这两行。
puts"Red, white, or something else?"
user_category_selection = gets.chomp.downcase
puts "-"*80
wine_rack = [
{ name: "The Fugitive",
vintage: 2010,
category: "Red",
grape_composition: "Red Blend",
location: "Napa, California",
personal_rating: 91},
{ name: "Au Bon Climat",
vintage: 2010,
category: "White",
grape_composition: "Chardonnay",
location: "Santa Barbara, California",
personal_rating: 89},
{ name: "Laurent-Perrier",
vintage: "Non-vintage",
category: "Something Else",
grape_composition: "Ultra Brut",
location: "France",
personal_rating: 92}
]
这是不起作用的部分:
def vintage_name_location(category)
category = wine_rack[:category].downcase
while category.downcase.include? user_category_selection
puts "#{wine[:vintage]} #{wine[:name]}, #{wine[:location]}".center(80)
puts "#{wine[:grape_composition]}, rated #{wine[:personal_rating]} points".center(80)
end
end
puts vintage_name_location(user_category_selection)
剩下的代码是:
until ["white", "red", "something else"].include? user_category_selection.downcase
puts "Pardon me for asking, but are you intoxicated already?".center(80)
puts "I said red, white, or something else.".center(80)
user_category_selection = gets.chomp
end
if user_category_selection.downcase.eql? "red"
puts "May I suggest one of these delightful reds:"
puts "--------------------------------------------------".center(80)
for wine in wine_rack
if wine[:category].downcase == user_category_selection
puts "#{wine[:vintage]} #{wine[:name]}, #{wine[:location]}".center(80)
puts "#{wine[:grape_composition]}, rated #{wine[:personal_rating]} points".center(80)
puts "--------------------------------------------------".center(80)
end
end
elsif user_category_selection.downcase.eql? "white"
正如您正确描述的那样,您的 wine_rack
是一个数组,因此您无法使用这样的类别名称查找项目:wine_rack[:category]
.
一种方法是使用 select
来挑选符合以下类别的葡萄酒:
matching_wines = wine_rack.select { |wine| wine[:category].downcase == category }
您可以像这样将其包装在您的函数中:
def wines_in_category(category)
wine_rack.select { |wine| wine[:category].downcase == category }
end
然后像这样使用它:
suitable_wines = wines_in_category(user_category_selection)
for wine in suitable_wines
...
这是另一个解决方案,指出了您必须使用哪些变量。
请注意,您无法直接从该方法与 wine_rack
进行交互。可以使用send
方法打开作用域门,也可以只传入wine_rack
数组
此外,Array#select
将 return 块 return 为真的所有实例。这现在可能不会影响您的软件,但以后可能会导致问题:
puts "Variables I have to work with: #{local_variables}"
def get_wine_information(passed_wine_rack,user_selection)
puts "Variables I have to work with inside method: #{local_variables}"
selection = passed_wine_rack.find {|wine| wine[:category] == user_selection}
puts "#{selection[:vintage]} #{selection[:name]}, #{selection[:location]}"
puts "#{selection[:grape_composition]}, rated #{selection[:personal_rating]} points"
end
#Scope Gate
Kernel.send(:define_method, :get_wine_info) do |user_selection|
puts "Variables I have to work with inside scope gate: #{local_variables}"
end
#Calling just to see scope information
get_wine_info("")
get_wine_information(wine_rack,user_category_selection)