Accessing a hash -- Beginner

I want to access a hash via a gets command. A simplified
example, for a hash named, "test":

  print 'hash name: '
  hash_var = gets.chomp # enter 'test' here

  puts hash_var # <-- nil
  puts test # <-- the contents of the hash
  
One problem I see is hash_var is class String, while test is
class Hash. I cannot figure out how to make hash_var class
Hash. I'm not even sure if I am on the right track. I
would appreciate any help.

Thanks in advance,

Don

Hi --

I want to access a hash via a gets command. A simplified
example, for a hash named, "test":

print 'hash name: '
hash_var = gets.chomp # enter 'test' here

puts hash_var # <-- nil
puts test # <-- the contents of the hash

One problem I see is hash_var is class String, while test is
class Hash. I cannot figure out how to make hash_var class
Hash. I'm not even sure if I am on the right track. I
would appreciate any help.

Do you want to set a hash key, or retrieve a value using an existing
key? For example:

   test = { "one" => 1, "two" => 2 }
   hash_key = gets.chomp
   puts test[hash_key]

If you input "one", the program will print 1.

David

···

On Sat, 4 Nov 2006, don wrote:

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

don wrote:

I want to access a hash via a gets command. A simplified example, for a hash named, "test":
   print 'hash name: '
  hash_var = gets.chomp # enter 'test' here

  puts hash_var # <-- nil
  puts test # <-- the contents of the hash
  One problem I see is hash_var is class String, while test is
class Hash. I cannot figure out how to make hash_var class
Hash. I'm not even sure if I am on the right track. I
would appreciate any help.

There is not a single Hash instance in your code. Also "test" is not set, hence it's interpreted as a method call:

$ ruby -e " print 'hash name: '
> hash_var = gets.chomp # enter 'test' here
>
> puts hash_var # <-- nil
> puts test # <-- the contents of the hash
> "
hash name: foo
foo
-e:5:in `test': wrong number of arguments (ArgumentError)
         from -e:5

What is your problem? What are you trying to achieve?

Regards

  robert

don wrote:

I want to access a hash via a gets command. A simplified example, for a hash named, "test":
   print 'hash name: '
  hash_var = gets.chomp # enter 'test' here

  puts hash_var # <-- nil
  puts test # <-- the contents of the hash
  One problem I see is hash_var is class String, while test is
class Hash. I cannot figure out how to make hash_var class
Hash. I'm not even sure if I am on the right track. I
would appreciate any help.

The trick is that you want the variable named test, while the return from gets is a string. You can use eval to evaluate a string in the current context, so this works (but is VERY dangerous, read on):

test = {:foo => 'bar'}
p eval('test')
#=> {:foo=>"bar"}

This approach will execute any Ruby code that happens to be typed in by the user, which is obviously bad:

p eval('test = nil')
p test
#=> nil

One approach might be to gsub out any non word characters (but this still makes me a bit queasy):

p eval('test'.gsub(/\W/, ''))
#=> {:foo=>"bar"}

p eval('test = nil'.gsub(/\W/, ''))
NameError: undefined local variable or method `testnil' for main:Object
        from (irb):11

Hope this helps.

Tom

Tom Werner wrote:

don wrote:

I want to access a hash via a gets command. A simplified example, for a hash named, "test":
   print 'hash name: '
  hash_var = gets.chomp # enter 'test' here

  puts hash_var # <-- nil
  puts test # <-- the contents of the hash
  One problem I see is hash_var is class String, while test is
class Hash. I cannot figure out how to make hash_var class
Hash. I'm not even sure if I am on the right track. I
would appreciate any help.

One approach might be to gsub out any non word characters (but this still makes me a bit queasy):

p eval('test'.gsub(/\W/, ''))
#=> {:foo=>"bar"}

On further consideration, even this is futile. Consider:

p eval('exit')

Which leaves you back on the command line. What you want to do is create a Hash that contains the hash you are interested in:

test = {:foo => 'bar'}
shelf = {'test' => test}

Now you can look up the Hash of interest by name:

p shelf['test']
#=> #=> {:foo=>"bar"}

eval is dangerous. VERY DANGEROUS.

Tom

[...]

There is not a single Hash instance in your code. Also "test" is not
set, hence it's interpreted as a method call:

$ ruby -e " print 'hash name: '
> hash_var = gets.chomp # enter 'test' here
>
> puts hash_var # <-- nil
> puts test # <-- the contents of the hash
> "
hash name: foo
foo
-e:5:in `test': wrong number of arguments (ArgumentError)
         from -e:5

What is your problem? What are you trying to achieve?

Robert, thanks for the response. Part of my problem is I
did not communicate my problem very well. I will try again
a little later.

Don

···

On 2006-11-03, Robert Klemme wrote:

I want to access the hash, then print part of the contents.
I am going to restate my problem -- hopefully a little
clearer -- later.

Thanks for the response, David.

Don

···

On 2006-11-03, dblack@wobblini.net wrote:

Do you want to set a hash key, or retrieve a value using an existing
key? For example:

   test = { "one" => 1, "two" => 2 }
   hash_key = gets.chomp
   puts test[hash_key]

If you input "one", the program will print 1.

Tom Werner wrote:

[...]

One approach might be to gsub out any non word characters (but this
still makes me a bit queasy):

p eval('test'.gsub(/\W/, ''))
#=> {:foo=>"bar"}

On further consideration, even this is futile. Consider:

p eval('exit')

Which leaves you back on the command line. What you want to do is create
a Hash that contains the hash you are interested in:

test = {:foo => 'bar'}
shelf = {'test' => test}

Now you can look up the Hash of interest by name:

p shelf['test']
#=> #=> {:foo=>"bar"}

eval is dangerous. VERY DANGEROUS.

Tom

Thanks Tom. I will skip eval for now. I am going to repose
my question as I did not do a very good job the first time.

Don

···

On 2006-11-03, Tom Werner wrote:

I think I did a poor job of communicating my problem. I do
not think it is a complicated one, although it might be. I
know very little about programming.

I have 32 hashes. I would like to key in a hash name and
extract data from it. Like this:

  Enter team: (Enter 'ari', for example)
  team_var = gets.chomp
  puts team_var['coach']

Above does not work. For one thing, ari is actually $ari.
  team_var = '$' + team_var does not work either.

So simply put, how do you call a hash by name interactively?

Below is an example of what my code would look like:

$ari = {
  'name' => 'Arizona Cardinals',
  'team_notes' => 'skank team',
  'qb' => 'Matt Leinart, Kurt Warner',
  'qb_rank' => '',
  'cbs' => '',
  'espn' => '',
  'players' => 'rb Edgerrin James',
  'coach' => 'Denny Green',
  'weekly_notes' => ' wk01 Fitzgerald 133 yds.'
}

  print 'team: '
  team = gets.chomp
  team = '$' + team
  puts team['coach']

Thanks in advance for your help.

Don

I have 32 hashes. I would like to key in a hash name and
extract data from it. Like this:

  Enter team: (Enter 'ari', for example)
  team_var = gets.chomp
  puts team_var['coach']

You could stick (or create from the beginning) those hashes into another
hash, say "teams," and then you'll be able to get them by indexing
"teams" with user input.

Above does not work. For one thing, ari is actually $ari.
  team_var = '$' + team_var does not work either.

So simply put, how do you call a hash by name interactively?

Below is an example of what my code would look like:

$ari = {
  'name' => 'Arizona Cardinals',
  'team_notes' => 'skank team',
  'qb' => 'Matt Leinart, Kurt Warner',
  'qb_rank' => '',
  'cbs' => '',
  'espn' => '',
  'players' => 'rb Edgerrin James',
  'coach' => 'Denny Green',
  'weekly_notes' => ' wk01 Fitzgerald 133 yds.'
}

  teams = {} # Create a new hash to store the individual team hashes
  teams['ari'] = $ari

  print 'team: '
  team = gets.chomp

then change the above^ to
    team = teams[gets.chomp]
and you can proceed with

  puts team['coach']

You'll still want some error-checking (what if the user enters
'akaskdfj'?), of course.

You can also now access the elements of the individual teams like
"teams['ari']['coach']" if you want, although it will often be less
cluttered-looking if you pull a reference to the individual team out
before you go to work on it, as "team = teams[gets.chomp]" does.

···

On 2006-11-04, don <donsdx@gmailSPAMBAD.invalid> wrote:

I have 32 hashes. I would like to key in a hash name and
extract data from it. Like this:

  Enter team: (Enter 'ari', for example)
  team_var = gets.chomp
  puts team_var['coach']

You could stick (or create from the beginning) those hashes into another
hash, say "teams," and then you'll be able to get them by indexing
"teams" with user input.

[...]

  teams = {} # Create a new hash to store the individual team hashes
  teams['ari'] = $ari

  print 'team: '
  team = gets.chomp

then change the above^ to
    team = teams[gets.chomp]
and you can proceed with

  puts team['coach']

You'll still want some error-checking (what if the user enters
'akaskdfj'?), of course.

You can also now access the elements of the individual teams like
"teams['ari']['coach']" if you want, although it will often be less
cluttered-looking if you pull a reference to the individual team out
before you go to work on it, as "team = teams[gets.chomp]" does.

Excellent, Jim. That's what I will do.

Thak you. Take care.

Don

···

On 2006-11-03, Jim Marshall wrote:

On 2006-11-04, don <donsdx@gmailSPAMBAD.invalid> wrote: