Reading the comments, I think you should first make yourself familiar with the basic building blocks and the syntax of Ruby.
I know, in the beginning I had tons of similar questions.
I found a very basic and playful approach to learn the basics of the Ruby programming language in this book.
To answer your question:
CSV.foreach(csv_file_name, header: true)
is a method call to CSV
. The method foreach
in this case receives two arguments.
csv_file_name
is a variable that is being defined as the first argument of the outer method read_in_csv_data
.
So if you call CsvReader.new.read_in_csv_data("file.csv")
it will pass the string "file.csv"
down to CSV.foreach("file.csv", ...
.
header: true
is basically a Hash, but this style is commonly known as named arguments. Very useful and readable if you want to pass down options to a method that are very specific.
How does CSV.foreach
receive header: true
?
That is easy to find out, open up a $ irb
session on your local machine, and define the following method:
def foo(arg1, arg2)
p arg1
p arg2
nil
end
Now play around by calling foo
with different arguments.
> foo("string", 123)
"string"
123
=> nil
> foo("string", named: "argument")
"string"
{:named=>"argument}
=> nil
> foo("string", { named: "argument" })
"string"
{:named=>"argument}
=> nil
Doing this you might grasp how Ruby handles named arguments or hash arguments. As you see, the latter examples above show that you can specify a Hash without {}
as the last argument on any method in Ruby.
header: true
represents a Hash, ie {:header => true}
.
What does header: true
trigger?
This has to be read up in the documentation for CSV::foreach
. You you do a Google search for "ruby csv foreach" you will quickly find a documentation. Here is a direct link to CSV::foreach
.
There you can read "The options parameter can be anything ::new understands.". So you gotta look for the documentation of CSV::new
. This leads you to a nice description of each option you can pass to CSV::new
or CSV::foreach
.
What does the documentation say?
:headers If set to :first_row or true, the initial row of the CSV file
will be treated as a row of headers. If set to an Array, the contents
will be used as the headers. If set to a String, the String is run
through a call of ::parse_line with the same :col_sep, :row_sep, and
:quote_char as this instance to produce an Array of headers. This
setting causes #shift to return rows as CSV::Row objects instead of
Arrays and #read to return CSV::Table objects instead of an Array of
Arrays.
Your other questions:
You are welcome to ask questions, but I also think it would be very good for you to get someone to help you directly. Maybe find yourself a local Ruby user group. People there are usually very friendly and helpful.
Having said that, I will now explain what row["ISBN"]
means:
CSV::foreach
is a method that yields a block. This block is somewhat similar to a function, and per definition of CSV::foreach
it lets you do something with each row of the csv file.
row
itself is just a variable name defined in the block arguments (ie |row|
).
Maybe its time for you to open up another $ irb
and play around with blocks yourself:
def foo
yield 123
end
Try calling foo the same way as you do CSV::foreach
, just that you print the output.
> foo do |row| puts row end
123
=> nil
> foo { |arg1| puts arg1 }
123
=> nil
As you see yield 123
is passing 123
as the first argument of the block. You take the first argument in a variable (eg row
or arg1
) and you can do something with it in the block. Also note that you can create these blocks with do |arg1| ... end
but also { |arg1| ... }
.
So what is it with this ["ISBN"]
??
row
itself is just a variable, but is also an object so you can call methods on it. In Ruby you might have already encountered a hash.
The contents of a hash in Ruby can be accessed by calling []
on the hash.
The same way each row of the CSV is represented. Just that each row (since you told CSV
to use :headers) is being represented as a hash-like object.
If you omit :headers each row will be an array of arrays.
Maybe its time for you to open up an $ irb
and play around with CSV
directly. For that create yourself a simple csv file like the following, and save it to disk:
id,name
1,Overbryd
2,Boniface
3,Poignant
Then, open up a $ irb -r csv
.
> CSV.foreach("test.csv") { |r| p r }
["id", "name"]
["1", "Overbryd"]
["2", "Boniface"]
["3", "Poignant"]
=> nil
> CSV.foreach("test.csv", headers: true) { |r| p r }
#<CSV::Row "id":"1" "name":"Overbryd">
#<CSV::Row "id":"2" "name":"Boniface">
#<CSV::Row "id":"3" "name":"Poignant">
=> nil
> CSV.foreach("test.csv", headers: true) do |row|
puts row["id"]
end
1
2
3
=> nil
Also, please accept one of the given answers. People take time to answer your questions, their only reward is if you accept one of their answers.