通过定义哈希数组的方法进行重构

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)