将方法参数链接到变量

时间:2015-08-16 16:18:36

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

我有一个程序,用户可以收到热门的“度假胜地”。他们要做的就是进入大陆(这将把他们带到那个词典),然后进入一个国家/州(这是哈希中的一个关键词),然后它会找到相应的值。

我有一个必需的文件(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方法有两个参数。第一个找到要使用的字典。如果我只是将northamerica作为一个参数,它就可以了。但是如果我改为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

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

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

据我了解你的意图,你希望用户输入成为一个变量名,用作第一个参数,但它没有办法神奇地发生,你最终只能传递一个字符串。< / p>

您需要做的是将用户输入显式映射到相应的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哈希,您可以轻松地使用案例陈述:

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)}"

希望这有帮助!

P.S。如果你不介意,还有两个建议:

  1. 在第二个参数中不需要字符串插值,像Dict.get(northamerica, country_select)这样的东西可能更清晰。
  2. 更好的变量命名可以帮助您避免头痛。即如果你将一个(相当误导的)country_select重命名为user_state_selection_string,它会提醒你它是一个字符串,以及它所拥有的字符串。这个例子是任意的。史蒂夫麦康奈尔有一本名为“代码完整”的精彩书籍,它比我更好地涵盖了这个和其他问题。