IO from text file

Info:

New to Ruby
Mac OSX with Ruby 1.8.7
Running from command line
Textmate editor

Question:

I am trying to read in three strings from a .txt file. The code does
everything but return the values stored in the file.

Code:

f = File.open(‘productlines.txt’,‘r’)

lines = f.readlines

lines.each do |line|

test = ‘#{line}’

puts ‘I read this line: ’ + test +’.’

end

File contents:
pkplus
aminoplex
tuffturf

Output:
I read this line: #{line}.
I read this line: #{line}.
I read this line: #{line}.
I read this line: #{line}.
I read this line: #{line}.

Not sure if I am reading file correctly or why it return five times?
Thanks for your guidance.

Michael

Print the numbers of elements in lines. Most likely you have two blank
lines at
the end of the input file.

Also, notice how you are using single quotation marks, so you ruby won’t
expand the value of the variable line.

A more compact way to do it:

-drd

On 01/25/2011 04:46 PM, Michael L. wrote:

test = ‘#{line}’
^^^^^^^^^
You need to use double quotes rather than single quotes here. Single
quotes are meant to be used when you are likely to be defining string
contents that might otherwise be evaluated under double quotes.
Basically, you can more safely avoid escaping characters that have
special meaning. In your case, you want to have the evaluation
performed, so you need the double quotes. :slight_smile:

-Jeremy

Thanks for the excellent advice as I now have the correct information
when I run the code. I am slowly working on a program where I ask a user
for a selection, compare the selection to a file, then assign that
selection(two pieces of information) to a variable to be used later.

In your opinion should this data file be YAML, csv, or something else? I
am only looking at less than 100 records.

Thanks

Michael

On Wed, Jan 26, 2011 at 3:19 AM, Jeremy B. [email protected] wrote:

lines.each do |line|

test = ‘#{line}’
^^^^^^^^^
You need to use double quotes rather than single quotes here. Single
quotes are meant to be used when you are likely to be defining string
contents that might otherwise be evaluated under double quotes.
Basically, you can more safely avoid escaping characters that have
special meaning. In your case, you want to have the evaluation
performed, so you need the double quotes. :slight_smile:

Note also that in this particular string evaluation is completely
superfluous since the string around #{line} is empty, i.e. adds
nothing. Basically this is sufficient

lines.each do |line|
line.chomp! # remove trailing nl
puts “I read this line: #{line}.”
end

You can as well do

File.foreach do |line|
line.chomp! # remove trailing nl
puts “I read this line: #{line}.”
end

Kind regards

robert

On Wed, Jan 26, 2011 at 1:04 PM, Michael L. [email protected]
wrote:

Thanks for the excellent advice as I now have the correct information
when I run the code. I am slowly working on a program where I ask a user
for a selection, compare the selection to a file, then assign that
selection(two pieces of information) to a variable to be used later.

In your opinion should this data file be YAML, csv, or something else? I
am only looking at less than 100 records.

The format of that file does not really matter - all these are proper
options. I suggest you base your decision on what’s most convenient
for the producer of the file (user manual typing, spreadsheet or
database export, …).

If you want to ask the user multiple times and given the size of the
file you should consider loading the file into a data structure which
gives you efficient access (e.g. a Hash with proper key values) so you
don’t have to read the file repeatedly. This will be faster than
having to go to the file over and over again. If you use YAML you can
directly load the file into the Hash:

14:54:54 Temp$ irb19 -r yaml
Ruby version 1.9.2
irb(main):001:0> h={};10.times {|i| h[“key #{i}”]=“value #{i}”}
=> 10
irb(main):002:0> h
=> {“key 0”=>“value 0”, “key 1”=>“value 1”, “key 2”=>“value 2”, “key
3”=>“value 3”, “key 4”=>“value 4”, “key 5”=>“value 5”, “key 6”=>“value
6”, “key 7”=>“value 7”, “key 8”=>“value 8”, “key 9”=>“value 9”}
irb(main):003:0> s = h.to_yaml
=> “— \nkey 0: value 0\nkey 1: value 1\nkey 2: value 2\nkey 3: value
3\nkey 4: value 4\nkey 5: value 5\nkey 6: value 6\nkey 7: value 7\nkey
8: value 8\nkey 9: value 9\n”
irb(main):004:0> puts s

key 0: value 0
key 1: value 1
key 2: value 2
key 3: value 3
key 4: value 4
key 5: value 5
key 6: value 6
key 7: value 7
key 8: value 8
key 9: value 9
=> nil
irb(main):005:0> h2 = YAML.load(s)
=> {“key 0”=>“value 0”, “key 1”=>“value 1”, “key 2”=>“value 2”, “key
3”=>“value 3”, “key 4”=>“value 4”, “key 5”=>“value 5”, “key 6”=>“value
6”, “key 7”=>“value 7”, “key 8”=>“value 8”, “key 9”=>“value 9”}
irb(main):006:0> h == h2
=> true
irb(main):007:0>

For reading YAML from a file you can use a 1liner:

hash = File.open(“data”) {|io| YAML.load(io)}

Kind regards

robert