2

So I've seen questions on here about how to write to an external text file etc. For example to write my hash to another file I put:

hash = {
  Key1: Value1,
  Key2: Value2
}
open(FileToWriteTo, 'w') do |f|
  hash.each { |key, value| f.puts "#{key}: #{value}" }

But what I'd like to achieve is if I run the program and add something to my hash list, then the next time I run and display the hash, the new addition will be there. Here's the code I'm using to add to my hash:

puts "Type 'add' to add an item to the hash"

choice = gets.chomp.downcase

case choice
when 'add'
  puts "What do you want to add?"
  addition = gets.chomp
  if hash[addition.to_sym].nil?
    puts "What value will #{addition} have? (integer)"
    add_value = gets.chomp
    hash[addition.to_sym] = add_value.to_i
      puts "#{addition} has been added with a value of #{value}."
  else
    puts "That item already exists! Its value is #{hash[addition.to_sym]}."
end

So if I add the item, rerun the program and choose to display instead of add, how should I get the last addition to show. Thanks.

  • A side-note for CLI apps, take a look at [Thor](http://whatisthor.com) and [Thor::Shell::Basic#ask](http://www.rubydoc.info/github/wycats/thor/Thor%2FShell%2FBasic%3Aask) for some nice helpers. – dsample Mar 06 '16 at 01:23

2 Answers2

1

Here is code you could use. It takes advantage of yaml to store the hash.

require 'yaml'

file = '/tmp/test.yml'
if File.exists?(file)
  hash = YAML::load_file(file)  # load yaml
else
  hash = Hash.new
end

puts "Type 'add' to add an item to the hash"
choice = gets.chomp.downcase

if choice == 'add'
  puts "What do you want to add?"
  addition = gets.chomp
  if hash[addition.to_sym].nil?
    puts "What value will #{addition} have? (integer)"
    add_value = gets.chomp
    hash[addition.to_sym] = add_value.to_i
    puts "#{addition} has been added with a value of #{add_value}."
  else
    puts "That item already exists! Its value is #    {hash[addition.to_sym]}."
  end
end

File.open(file, 'w') {|f| f.write hash.to_yaml } #store yaml
Stephen Grimes
  • 398
  • 1
  • 7
  • Excellent. This is exactly what I was looking for. Thank you very much! And the yaml file will contain the complete hash right? meaning it will have saved hash = { Examplekey: Examplevalue } And it will load that exactly each time? – Ronnie Dineen Mar 06 '16 at 21:41
  • Yes, the yaml file contains the entire hash. Each time you run the code the hash will be rewritten to the yaml file. – Stephen Grimes Mar 06 '16 at 22:00
  • I'm getting this error: http://i.imgur.com/e62binv.png?..... file = 'tmp/test.yml' was the only line I changed and I changed it to the directory shown in that screenshot. – Ronnie Dineen Mar 06 '16 at 22:32
  • I discovered it was a syntax error in my test.yml file. It's working perfectly now. Thanks for your help. I also improved on your file/yaml block to `file = '/tmp/test.yml' hash = File.exists?(file) ? YAML::load_file(file): hash = Hash.new` Thanks for the help! – Ronnie Dineen Mar 07 '16 at 03:04
-1

If I understood the question correctly, you want to show the added option.

Since you are using the file and rerunning the code, better read the file (and store it in hash) at start and append new items (key-val) to file. So whenever anyone adds something, append it to file. Now when you read the file again at start, its updated.

Let me know if this is not your use case.

divyum
  • 1,286
  • 13
  • 20
  • I think you've got it, yes. – Ronnie Dineen Mar 06 '16 at 00:16
  • then you can use the solution I gave. :) – divyum Mar 06 '16 at 00:18
  • So if I want to add an item to hash, write it permanently to the file and be able to display it next time it's ran? – Ronnie Dineen Mar 06 '16 at 00:37
  • @divyum you've _described_ a possible solution without actually providing a solution for the OP. – Sagar Pandya Mar 06 '16 at 01:23
  • Take a look at [this answer](http://stackoverflow.com/a/3903698/931773). Using YAML would allow you to serialise and deserialise to a file. – dsample Mar 06 '16 at 01:28
  • Correct me if I'm wrong, But that talks about saving a hash to an external file like I mentioned above. I want to be able to save and close the current program. – Ronnie Dineen Mar 06 '16 at 01:52
  • @sagarpandya82 : the solution is pretty simplified, I guess code is not required. – divyum Mar 06 '16 at 06:40
  • @RonnieDineen using YAML is a good option. What exactly do you mean by save and close, can you explain a bit more. – divyum Mar 06 '16 at 06:44
  • For example: I run example.rb. I'm given the option to display a hash or add to it. I choose add. I enter what I want the key to be, then the value. After that, I'd like the hash to be updated to example.rb, not an external.yml file. So that if I run example.rb again and choose display I will see the updated hash. Is this possible or do I need to save to a .yml file? – Ronnie Dineen Mar 06 '16 at 22:52