A question about assignment of multidimensional array error message

Team,

The piece of code below is giving me an error which I can’t find the
solution. The assignment below for *
msgCount[r][c] = mtc *is trwoing an exception. which I list below.

Any suggestions?

###################################################################
#Date READ ENTRY DELETE ALARM HOTLIST SITE #
#20130611 2000000 200000 200000 2000 2000 20000 #
#20130611 2000000 200000 200000 2000 2000 20000 #
###################################################################

msgCount = Array.new # Empty array. Will have size of [r][7].
Rows will grow

fn = “/home/rb/MyData/dp/PR_LOGS/pr_time.log.*”

msgTypes = [“read”, “entry”, “delete”, “alarm”, “hotlist”, “site”]

fnls = ls #{fn}.split # Create fnls = file names list
fc = fnls.size # Number of files to be processed

fnls.each do |f| # Process each file
r = 0 # Rows are controlled by fnls, number of
files
lp,lg,dt = f.split(’.’) # this info will be used later

7.times do |c| # Process each column
mtc = grep #{msgTypes[c]} #{f} | wc -l # Get Message Type Count
msgCount[r][c] = mtc
r += 1 # Next row please
end
end

in block (2 levels) in <main>': undefined method[]=’ for
nil:NilClass
(NoMethodError)

Thank you

Check that msgCount[r] exists before this line:
msgCount[r][c] = mtc*

The approach you’re using with indices isn’t particularly Rubyish. I’d
use “each”, and add to the array with “<<”

On Fri, Jun 21, 2013 at 6:16 PM, Ruby S.
[email protected]wrote:

Team,

The piece of code below is giving me an error which I can’t find the
solution. The assignment below for *
msgCount[r][c] = mtc *is trwoing an exception. which I list below.

Any suggestions?

Yes, a lot. First of all your Ruby is not very idiomatic. The smallest
issue is your naming with camelCase which in Ruby land is only used for
class and module names. All others use snake_case.

###################################################################
#Date READ ENTRY DELETE ALARM HOTLIST SITE #
#20130611 2000000 200000 200000 2000 2000 20000 #
#20130611 2000000 200000 200000 2000 2000 20000 #
###################################################################

Is this above the file format? With or without all the hashes?

msgCount = Array.new # Empty array. Will have size of [r][7].
Rows will grow

fn = “/home/rb/MyData/dp/PR_LOGS/pr_time.log.*”

msgTypes = [“read”, “entry”, “delete”, “alarm”, “hotlist”, “site”]

fnls = ls #{fn}.split # Create fnls = file names list

Don’t use backticks for this. Just use

file_name_list = Dir[“/home/rb/MyData/dp/PR_LOGS/pr_time.log.*”]

fc = fnls.size # Number of files to be processed

fnls.each do |f| # Process each file
r = 0 # Rows are controlled by fnls, number of
files

Do you really want to reset r to 0 for every file? That will mean that
you
will later be overwriting values when you do msgCount[r][c] = mtc. I
don’t
think that is what you want.

lp,lg,dt = f.split(‘.’) # this info will be used later

7.times do |c| # Process each column
mtc = grep #{msgTypes[c]} #{f} | wc -l # Get Message Type Count

I am not sure what the line above is supposed to do. What it currently
does is this: it searches in the current file for all lines containing
the current “message type” and then counts the number of those lines.
Btw,
you can do the counting with “grep -c”.

This approach is quite inefficient because it will read each file 7
times.
Oh wait, and there are only 6 elements in msgType! One more reason not
to
use a number to iterate the array but just use #each as everybody else.

  *msgCount[r][c] = mtc*
  r += 1                    # Next row please

You are incrementing r 7 * # of file names. Is this really what you
want?
Don’t you rather want to store counts per file?

end

end

A more idiomatic way of doing what you are probably trying to do is
this:
store counts in nested Hashes based on file name and message type.

msg_types = [“read”, “entry”, “delete”, “alarm”, “hotlist”, “site”]

line_counts = {}

Dir[“/home/rb/MyData/dp/PR_LOGS/pr_time.log.*”].each do |file_name|

better: ARGV.each do |file_name|

counts = Hash.new 0

File.foreach file_name do |line|
msg_types.each do |mt|
counts[mt] += 1 if line.include? mt
end
end

line_counts[file_name] = counts
end

output for testing purposes only

require ‘pp’
pp line_counts

in block (2 levels) in <main>': undefined method []=’ for nil:NilClass
(NoMethodError)

Joel has explained that already.

Cheers

robert