Newbie problem with a hash

I've got a file which I've read in and split to make a hash like this:

def initialize(fname)
  @data=Hash.new
  begin
  IO.foreach(fname) do |line|
    key,value=line.chomp.split(":")
    @data[key]=value
  end
end

This gives a hash keyed on the first field of the file, where : is the
separator. (NB How do I handle : in the data - prompt to self!)

But when I try to get the value associated with that key by a fetch, I get
and IndexError:

def get_datum(datid) # Typical datid is $01 - I've stripped off the colon.
if $debug
   print("Getting data for id [#{datid}]\n") # Prints $01
end

begin
  #@data.fetch("$01") - this works OK,
  @data.fetch(datid) # This causes an IndexError
  rescue IndexError => err
    print("No data for key [#{datid}] : #{err}\n")
    @data.each do |key,val|
            printf("Key [%s] => [%s]\n",key,val) # Shows $01 => avalue (amongst
others)
    end
    exit(NO_DATA)
end
end

I'm racking my brains, but to no avail. If I put the key in as a literal,
it returns, but using the datid variable, I get an IndexError.

I'd appreciate a pointer - its probably something daft - it usually is, but
I haven't got a cardboard analyst.

PS I rather like Ruby - its more elegant than Python (but don't tell anyone
in c.l.python!), IMNSHO.
Graham

···

--
#include wit

How are you calling get_datum? Show us the line where you call it that gives
you that error.

  Sean O'Dell

···

On Monday 21 June 2004 11:08, Graham Nicholls wrote:

I've got a file which I've read in and split to make a hash like this:

def initialize(fname)
  @data=Hash.new
  begin
  IO.foreach(fname) do |line|
    key,value=line.chomp.split(":")
    @data[key]=value
  end
end

This gives a hash keyed on the first field of the file, where : is the
separator. (NB How do I handle : in the data - prompt to self!)

But when I try to get the value associated with that key by a fetch, I get
and IndexError:

def get_datum(datid) # Typical datid is $01 - I've stripped off the colon.
if $debug
   print("Getting data for id [#{datid}]\n") # Prints $01
end

begin
  #@data.fetch("$01") - this works OK,
  @data.fetch(datid) # This causes an IndexError
  rescue IndexError => err
    print("No data for key [#{datid}] : #{err}\n")
    @data.each do |key,val|
            printf("Key [%s] => [%s]\n",key,val) # Shows $01 => avalue
(amongst others)
    end
    exit(NO_DATA)
end
end

I'm racking my brains, but to no avail. If I put the key in as a literal,
it returns, but using the datid variable, I get an IndexError.

I've got a file which I've read in and split to make a hash like this:

def initialize(fname)
  @data=Hash.new
  begin
  IO.foreach(fname) do |line|
    key,value=line.chomp.split(":")
    @data[key]=value
  end
end

This gives a hash keyed on the first field of the file, where : is the
separator. (NB How do I handle : in the data - prompt to self!)

But when I try to get the value associated with that key by a fetch, I get
and IndexError:

def get_datum(datid) # Typical datid is $01 - I've stripped off the colon.
if $debug
   print("Getting data for id [#{datid}]\n") # Prints $01
end

begin
  #@data.fetch("$01") - this works OK,
  @data.fetch(datid) # This causes an IndexError
  rescue IndexError => err
    print("No data for key [#{datid}] : #{err}\n")
    @data.each do |key,val|
            printf("Key [%s] => [%s]\n",key,val) # Shows $01 => avalue (amongst
others)
    end
    exit(NO_DATA)
end
end

Where did you get 'datid'? Are you absolutely positive it's a String? I would suggest inspect()ing the variable in the debug statement. In fact, I would suggest doing several tests on the contents of the variable there, printing out datid.class, (datid =~ /\A\$\d\d\z/), etc...

and, (less importantly) I would remove some code there, just to make less code to check :slight_smile:

   def get_datum(datid)
     if $debug
       puts "Getting data for id [#{datid.inspect}]" # inspect it
       puts "class: #{datid.class}" # check the class
       puts "valid? #{datid =~ /\A\$\d\d\z/}" # check via regexp matching
       puts "@data.has_key? #{@data.has_key? datid}" # is there a key there?
     end
     @data.fetch(datid)
   rescue IndexError => err
     puts "No data for key [#{datid}] : #{err}"
     @data.each {|k,v| puts "Key #{k} => #{v}"}
   end

I'm racking my brains, but to no avail. If I put the key in as a literal,
it returns, but using the datid variable, I get an IndexError.

There really should be absolutely no difference between using a variable and using a literal... I strongly suspect that somehow you are not getting the data your function expects.

Oh, and "Welcome!"

HTH,
Mark

···

On Jun 21, 2004, at 11:08 AM, Graham Nicholls wrote:

I'd appreciate a pointer - its probably something daft - it usually is, but
I haven't got a cardboard analyst.

PS I rather like Ruby - its more elegant than Python (but don't tell anyone
in c.l.python!), IMNSHO.
Graham
--
#include wit

Sean O'Dell wrote:

···

On Monday 21 June 2004 11:08, Graham Nicholls wrote:

I've got a file which I've read in and split to make a hash like this:

def initialize(fname)
  @data=Hash.new
  begin
  IO.foreach(fname) do |line|
    key,value=line.chomp.split(":")
    @data[key]=value
  end
end

This gives a hash keyed on the first field of the file, where : is the
separator. (NB How do I handle : in the data - prompt to
self!)

But when I try to get the value associated with that key by a fetch, I
get and IndexError:

def get_datum(datid) # Typical datid is $01 - I've stripped off the
colon.
if $debug
   print("Getting data for id [#{datid}]\n") # Prints $01
end

begin
  #@data.fetch("$01") - this works OK,
  @data.fetch(datid) # This causes an IndexError
  rescue IndexError => err
    print("No data for key [#{datid}] : #{err}\n")
    @data.each do |key,val|
            printf("Key [%s] => [%s]\n",key,val) # Shows $01 => avalue
(amongst others)
    end
    exit(NO_DATA)
end
end

I'm racking my brains, but to no avail. If I put the key in as a
literal, it returns, but using the datid variable, I get an IndexError.

How are you calling get_datum? Show us the line where you call it that
gives you that error.

Sean O'Dell

printf("%s",datid.class)

told me it was an array - what a nitwit! Now sorted.
Thanks, both.
Graham
--
#include wit