5

I am trying to use a CSV as a settings file in a plugin for the SiriProxy project to use wake-on-lan. This project is based on ruby.

So the csv is as follows:

Name, MACAddress
Desktop, 01-23-45-67-89-ab
Computer, 02-46-81-02-46-cd

and so on...

So what I would like to happen is that when the variable userAction is "Desktop" for instance, then I query the CSV and it returns the MAC address into another variable. I am lost on how to do this. I have seen the csv and faster_csv but do not know how to get those to work like this.

Thanks in advance!

zed_0xff
  • 32,417
  • 7
  • 53
  • 72
IMcD23
  • 445
  • 1
  • 7
  • 13

2 Answers2

10

If you try to use FasterCSV in Ruby 1.9 you get a warning saying that the standard Ruby 1.9 CSV library is actually faster. So I used the standard Ruby CSV library. This should work in Ruby 1.9 or 1.8.7.

require 'csv'

module MyConfig
  @mac_address_hash = {}
  CSV.foreach("config.csv") do |row|
    name, mac_address = row
    next if name == "Name"
    @mac_address_hash[name] = mac_address
  end

  puts "Now we have this hash: " + @mac_address_hash.inspect

  def self.mac_address(computer_name)
    @mac_address_hash[computer_name]
  end

end

puts "MAC address of Desktop: " + MyConfig.mac_address("Desktop")

The output of this code is:

Now we have this hash: {"Computer"=>" 02-46-81-02-46-cd", "Desktop"=>" 01-23-45-67-89-ab"}
MAC address of Desktop:  01-23-45-67-89-ab

Now what I want you to do is read every line of this code carefully and try to understand what it does and why it is necessary. This will make you a better programmer in the long run.

You could improve this code to lazily load the CSV file the first time it is required.

David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • Thanks a bunch! I was almost there. You are the best – IMcD23 Dec 11 '11 at 19:36
  • This solution is way too complicated; @steenslag's is much more idiomatic. I've included a comment to show how the result of CSV.read() can be converted to a Hash. – dancow Sep 15 '18 at 21:16
7

I'll demonstrate the dirt-simple method. Stuffing everything in a hash as David Grayson did is far more efficient in the long run, but for a run-a-few-times script this might be sufficient.

require 'csv'
config = CSV.read('config.csv')
config.shift # Get rid of the header
# We're done! Start using like so:
p config.assoc("Computer").last #=>" 02-46-81-02-46-cd" 

If the leading space is unwanted:

config = CSV.read('config.csv', {:col_sep => ', '})
steenslag
  • 79,051
  • 16
  • 138
  • 171
  • 1
    This should be the answer, with one addition -- the use of `Hash[arr]` will convert the result of `CSV.read()` -- i.e. an array of arrays -- to a Hash: `Hash[CSV.read('config.csv', col_sep: ', ')]` – dancow Sep 15 '18 at 21:17