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
--
Ruby Student

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 "<<"

···

--
Posted via http://www.ruby-forum.com/.

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

···

On Fri, Jun 21, 2013 at 6:16 PM, Ruby Student <ruby.student@gmail.com>wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/