ruby on rails - Link method argument to a variable -
i have program user able receive popular "vacation spots". al have enter continent (which bring them dictionary) , enter country/state (which key in hash) , find corresponding value.
i have required file (dict.rb) hash module using arrays.
but issue have small. assigned user input 2 variables, continent_select
, country_select
here's code:
require './dict.rb' #create new dictionary called northamerica northamerica = dict.new dict.set(northamerica, "new york", "new york city") dict.set(northamerica, "new jersey", "belmar") puts "welcome vacation hub" puts "what continent interested in?" print '> ' continent_select = $stdin.gets.chomp.downcase continent_select.gsub!(/\a"|"\z/, '') puts "which state go in #{continent_select}" print '> ' country_select = $stdin.gets.chomp.downcase #puts "you should go #{dict.get(northamerica, "#{country_select}")}" #=> should go belmar puts "you should go #{dict.get(continent_select, "#{country_select}")}" #=> error
ignore , set methods, they're in included dict.rb
anyway @ last few lines. dict.get
method has 2 arguments. first finds dictionary use. if put northamerica argument works. if put continent_select
instead (assuming user enters 'northamerica') doesn't work. think program looking dictionary named continent_select
, rather looking variable continent_select
.
update
here's whole dict.rb asked.
module dict #creates new dictionary user def dict.new(num_buckets=256) #initializes dict given num of buckets #creates adict variable empty array #that hold our values later adict = [] #loop through 0 number of buckets (0...num_buckets).each |i| #keeps adding arrays adict using push method adict.push([]) end return adict #returns [[],[],[]] => array of empty arrays reading go. end def dict.hash_key(adict, key) # given key create number , convert # index adict's buckets. return key.hash % adict.length #key.hash makes key number # % adict.length makes number between 1 , 256 end def dict.get_bucket(adict, key) #given key, find bucket go #sets key number , it's put in bucket_id variable bucket_id = dict.hash_key(adict, key) #finds key number in dict, , returns key return adict[bucket_id] end def dict.get_slot(adict, key, default=nil) #returns index, key, , value of slot found in bucket #assigns key name bucket variable bucket = dict.get_bucket(adict, key) bucket.each_with_index |kv, i| k, v = kv if key == k return i, k, v #returns index key found in, key, , value end end return -1, key, default end def dict.get(adict, key, default=nil) #gets value in bucket given key, or default i, k, v = dict.get_slot(adict, key, default=default) return v end def dict.set(adict, key, value) #sets key value, replacing existing value bucket = dict.get_bucket(adict, key) i, k, v = dict.get_slot(adict, key) if >= 0 bucket[i] = [key, value] else bucket.push([key, value]) end end def dict.delete(adict, key) #deletes. given key dict bucket = dict.get_bucket(adict, key) (0...bucket.length).each |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 dict adict.each |bucket| if bucket bucket.each {|k, v| puts k, v} end end end end
now there's weird stuff going on.
in first case, seems okay, pass correct arguments:
dict.get(northamerica, "#{country_select}")
that is: dict
instance first argument, , string
second. in second case:
dict.get(continent_select, "#{country_select}")
you pass string
instance instead of expected dict
, , results in error.
as far understand intention, want user input become variable name used first argument, there no way way magically happening, , end passing string.
what need explicitly map user input corresponding dict
object, , use it. can this:
# fetch dict object corresponds "northamerica" string hash # note: raise exception if user enters that's not present # in hash, i.e. other "northamerica" selected_continent_dict = { "northamerica" => northamerica }.fetch(continent_select) puts "you should go #{dict.get(selected_continent_dict, country_select)}"
if you're prohibited use ruby hashes, can away case statement:
selected_continent_dict = case continent_select when "northamerica" northamerica else raise "invalid continent" end puts "you should go #{dict.get(selected_continent_dict, country_select)}"
hope helps!
p.s. 2 more advice, if don't mind:
- there's no real need string interpolation in second argument, ,
dict.get(northamerica, country_select)
cleaner way. - better variable naming save headaches. i.e. if renamed (quite misleading)
country_select
user_state_selection_string
remind string, , of holds. example arbitrary though. there's wonderful book called "code complete" steve mcconnell covers , other issues better do.
Comments
Post a Comment