【问题标题】:Link method argument to a variable将方法参数链接到变量
【发布时间】:2015-08-16 16:18:36
【问题描述】:

我有一个程序,用户可以在其中接收流行的“度假地点”。他们所要做的就是输入大陆(这会将他们带到那个字典),然后输入一个国家/州(这是哈希中的一个键),然后它会找到相应的值。

我有一个必需的文件 (dict.rb),它基本上是一个使用数组的哈希模块。

但我遇到的问题相当小。我将用户输入分配给两个变量,continent_selectcountry_select

代码如下:

require './dict.rb'

#create a new dictionary called northamerica
northamerica = Dict.new
Dict.set(northamerica, "new york", "New York City")
Dict.set(northamerica, "new jersey", "Belmar")

puts "Welcome to The Vacation Hub"
puts "What continent are you interested in?"
print '> '

continent_select = $stdin.gets.chomp.downcase 
continent_select.gsub!(/\A"|"\Z/, '')

puts "Which state would you like to go to in #{continent_select}"
print '> '

country_select = $stdin.gets.chomp.downcase

#puts "You should go to #{Dict.get(northamerica, "#{country_select}")}"
#=> You should go to Belmar

puts "You should go to #{Dict.get(continent_select, "#{country_select}")}"
#=> error

忽略get和set方法,它们在包含的dict.rb中

无论如何,请仔细查看最后几行。 Dict.get 方法有两个参数。第一个查找要使用的字典。如果我只是把北美作为一个论点,它是有效的。但是如果我把continent_select 改为(假设用户输入'northamerica')它就不起作用。我认为该程序正在寻找名为continent_select字典,而不是寻找变量 continent_select

更新

这是为那些询问的人提供的整个 dict.rb。

module Dict
    #creates a new dictionary for the user
    def Dict.new(num_buckets=256)
        #initializes a Dict with given num of buckets
        #creates aDict variable which is an empty array
        #that will hold our values later
        aDict = []

        #loop through 0 to the number of buckets
        (0...num_buckets).each do |i|
            #keeps adding arrays to aDict using push method
            aDict.push([])
        end

        return aDict
        #returns [[],[],[]] => array of empty arrays reading to go.
    end

    def Dict.hash_key(aDict, key)
        # Given a key this will create a number and then convert
        # it to an index for the aDict's buckets.
        return key.hash % aDict.length
        #key.hash makes the key a number
        # % aDict.length makes the number between 1 and 256
    end
    def Dict.get_bucket(aDict, key)
        #given a key, find where the bucket would go
        #sets the key to a number and it's put in bucket_id variable
        bucket_id = Dict.hash_key(aDict, key)
        #finds the key number in the dict, and returns the key
        return aDict[bucket_id]
    end
    def Dict.get_slot(aDict, key, default=nil)
        #returns the index, key, and value of a slot found in a bucket
        #assigns the key name to the bucket variable
        bucket = Dict.get_bucket(aDict, key)

        bucket.each_with_index do |kv, i|
            k, v = kv
            if key == k
                return i, k, v
                #returns index key was found in, key, and value
            end
        end

        return -1, key, default
    end
    def Dict.get(aDict, key, default=nil)
        #Gets the value in a bucket for the given key, or the default
        i, k, v = Dict.get_slot(aDict, key, default=default)
        return v
    end
    def Dict.set(aDict, key, value)
        #sets the key to the value, replacing any existing value
        bucket = Dict.get_bucket(aDict, key)
        i, k, v = Dict.get_slot(aDict, key)

        if i >= 0
            bucket[i] = [key, value]
        else
            bucket.push([key, value])
        end
    end
    def Dict.delete(aDict, key)
        #deletes. the given key from the Dict
        bucket = Dict.get_bucket(aDict, key)

        (0...bucket.length).each do |i|
            k, v = bucket[i]
            if key == k
                bucket.delete_at(i)
                break
            end
        end
    end
    def Dict.list(aDict)
        #prints out what's in the dict
        aDict.each do |bucket|
            if bucket
                bucket.each {|k, v| puts k, v}
            end
        end
    end
end

【问题讨论】:

  • 如果您期望得到明确的答案,最好发布您的 dict.rb 实现,这样我们就不必猜测发生了什么。
  • @MarsAtomic 编辑帖子并添加 dict.rb

标签: ruby-on-rails ruby function methods arguments


【解决方案1】:

现在发生了一些奇怪的事情。

在第一种情况下,这似乎没问题,您传递了正确的参数:

Dict.get(northamerica, "#{country_select}")

即:Dict 实例作为第一个参数,String 作为第二个参数。但是在第二种情况下:

Dict.get(continent_select, "#{country_select}")

您传递了一个String 实例而不是一个明显预期的Dict,这会导致错误。

据我了解您的意图,您希望用户输入成为变量名以用作第一个参数,但它不可能神奇地发生,最终您只传递了一个字符串。

您需要做的是将用户输入显式映射到相应的Dict 对象,然后使用它。它可能看起来像这样:

# fetch a Dict object that corresponds to "northamerica" string from a hash
# NOTE: it will raise an exception if a user enters something that's not present
#       in a hash, i.e. something other than "northamerica"
selected_continent_dict = { "northamerica" => northamerica }.fetch(continent_select)
puts "You should go to #{Dict.get(selected_continent_dict, country_select)}"

如果您被禁止使用 Ruby 哈希,您可以轻松使用 case 语句:

selected_continent_dict = case continent_select
  when "northamerica"
    northamerica
  else
    raise "Invalid continent"
  end
puts "You should go to #{Dict.get(selected_continent_dict, country_select)}"

希望这会有所帮助!

附:如果您不介意,还有两个建议:

  1. 实际上不需要在第二个参数中进行字符串插值,Dict.get(northamerica, country_select) 之类的内容可能是一种更简洁的方法。
  2. 更好的变量命名可以让您免于烦恼。 IE。如果您将(相当误导的)country_select 重命名为user_state_selection_string,它会提醒您它是一个字符串,以及它所包含的内容。这个例子是任意的。史蒂夫·麦康奈尔 (Steve McConnell) 写了一本很棒的书,名为《代码完成》,它比我更好地涵盖了这个问题和其他问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2019-12-04
    • 2021-11-13
    • 2013-07-06
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多