Newbie file write problem

This is my first attempt at ruby. I've written a class (SicCode) which
parses a line and outputs a SQL command.

I use the following to read an input file and to attempt to write:

f = File.new("text.txt", "w")
File.open("small.txt").each {
>line>
s = SicCode.new(line).get_sql
f.puts "#{s}"
}
f.puts "This is a string"
f.close

The output file contains a blank line for each input line, plus the
"This is a string" line. If I change the put to f.puts s, I get a nil
for each input line. The get_sql method works fine interactively when
I pass the class a string.

What am I doing wrong?

Frustrated

Lars Zeb wrote:

This is my first attempt at ruby. I've written a class (SicCode) which
parses a line and outputs a SQL command.

I use the following to read an input file and to attempt to write:

f = File.new("text.txt", "w")
File.open("small.txt").each {
>line>
s = SicCode.new(line).get_sql

It sounds like your last line is the problem, so it doesn't have
anything to do with writing to a file. You are having trouble
retrieving the value for s.

···

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

If get_sql works in irb, it could be that the line endings in the file
are throwing it off. Try using:

SicCode.new(line.chomp).get_sql

and see if that works.

···

On Jan 29, 2:57 pm, Lars Zeb <lar...@gmail.com> wrote:

f = File.new("text.txt", "w")
File.open("small.txt").each {
>line>
s = SicCode.new(line).get_sql
f.puts "#{s}"
}
f.puts "This is a string"
f.close

The get_sql method works fine interactively when
I pass the class a string.

If I change to:

f = File.new("d:\downloads\\text.txt", "w")
File.open("D:\downloads\\SIC-small.txt").each {
>line>
s = SicCode.new(line.chomp).get_sql
f.puts s
}
f.puts "This is a string"
f.close

Each input line is written as nil to the output file. And I do see the
output I expect on the console.

If I change the script to:

File.open("D:\downloads\\SIC-small.txt").each {
>line>
s = SicCode.new(line).get_sql
puts s
}

I see the expected output to the console as well. If it matters, here
is the output for two lines:
      IF EXISTS (SELECT * FROM Sic WHERE Code = '3291')
      BEGIN
        UPDATE Sic
               SET Descr = 'ABRASIVE PRODUCTS'
               WHERE Code = '3291'
            END
         ELSE
            BEGIN
               INSERT INTO Sic
            SELECT '3291', 'ABRASIVE PRODUCTS', getdate()
         END
nil

      IF EXISTS (SELECT * FROM Sic WHERE Code = '6321')
      BEGIN
        UPDATE Sic
               SET Descr = 'ACCIDENT AND HEALTH INSURANCE'
               WHERE Code = '6321'
            END
         ELSE
            BEGIN
               INSERT INTO Sic
            SELECT '6321', 'ACCIDENT AND HEALTH INSURANCE', getdate()
         END

nil

Lars Zeb wrote:

Each input line is written as nil to the output file. And I do see the
output I expect on the console.

Hi,

It's time to stop asking us to debug imaginary code. Post a simple,
complete working example that is less than 20 lines and demonstrates
your problem.

···

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

Sorry, I can't do it in 20 lines, but it's very simple.

The class:
class SicCode
   def initialize(line)
      split_to_columns(line)
   end

   def split_to_columns(line)
      a = line.split(/\s+/)
      @sic = a[0]
      @descr = a.last(a.length - 1 ).join(" ")
   end

   def get_sic
      @sic
   end

   def get_descr
      @descr
   end

   def get_sql
      puts %Q{IF EXISTS (SELECT * FROM Sic WHERE Code = '#@sic')
      BEGIN
        UPDATE Sic
               SET Descr = '#@descr'
               WHERE Code = '#@sic'
            END
      ELSE
      BEGIN
  INSERT INTO Sic
  SELECT '#@sic', '#@descr', getdate()
      END
      }
   end
end

Input file(small.txt):
3291 ABRASIVE PRODUCTS
6321 ACCIDENT AND HEALTH INSURANCE
8720 ACCOUNTING, AUDITING, & BOOKKEEPING

Run this script:
irb(main):175:0> f = File.new("text.txt", "w")
=> #<File:d:downloads\text.txt>
irb(main):176:0> File.open("small.txt").each {
irb(main):177:1* |line|
irb(main):178:1* s = SicCode.new(line).get_sql
irb(main):179:1> f.puts s
irb(main):180:1> }
IF EXISTS (SELECT * FROM Sic WHERE Code = '3291')
      BEGIN
        UPDATE Sic
               SET Descr = 'ABRASIVE PRODUCTS'
               WHERE Code = '3291'
            END
         ELSE
            BEGIN
               INSERT INTO Sic
            SELECT '3291', 'ABRASIVE PRODUCTS', getdate()
         END

IF EXISTS (SELECT * FROM Sic WHERE Code = '6321')
      BEGIN
        UPDATE Sic
               SET Descr = 'ACCIDENT AND HEALTH INSURANCE'
               WHERE Code = '6321'
            END
         ELSE
            BEGIN
               INSERT INTO Sic
            SELECT '6321', 'ACCIDENT AND HEALTH INSURANCE', getdate()
         END

IF EXISTS (SELECT * FROM Sic WHERE Code = '8720')
      BEGIN
        UPDATE Sic
               SET Descr = 'ACCOUNTING, AUDITING, & BOOKKEEPING'
               WHERE Code = '8720'
            END
         ELSE
            BEGIN
               INSERT INTO Sic
            SELECT '8720', 'ACCOUNTING, AUDITING, & BOOKKEEPING',
getdate()
         END

Output file, text.txt, is empty (0 bytes).

Lars Zeb wrote:

   def get_sql
      puts %Q{IF EXISTS (SELECT * FROM Sic WHERE Code = '#@sic')
      BEGIN
        UPDATE Sic
               SET Descr = '#@descr'
               WHERE Code = '#@sic'
            END
      ELSE
      BEGIN
  INSERT INTO Sic
  SELECT '#@sic', '#@descr', getdate()
      END
      }
   end

irb(main):178:1* s = SicCode.new(line).get_sql

irb(main):179:1> f.puts s

What is s? s is assigned the return value of get_sql(). What's the
return value of get_sql?

···

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

Your problem has a simple fix -- remove the 'puts'. You want the string returned -- puts writes the string to stdout and returns nil.

Regards, Morton

···

On Jan 29, 2008, at 7:20 PM, Lars Zeb wrote:

   def get_sql
      puts %Q{IF EXISTS (SELECT * FROM Sic WHERE Code = '#@sic')
      BEGIN
        UPDATE Sic
               SET Descr = '#@descr'
               WHERE Code = '#@sic'
            END
      ELSE
      BEGIN
  INSERT INTO Sic
  SELECT '#@sic', '#@descr', getdate()
      END
      }
   end

I expected it was something like the following for each input line:
IF EXISTS (SELECT * FROM Sic WHERE Code = '3291')
      BEGIN
        UPDATE Sic
               SET Descr = 'ABRASIVE PRODUCTS'
               WHERE Code = '3291'
            END
         ELSE
            BEGIN
               INSERT INTO Sic
            SELECT '3291', 'ABRASIVE PRODUCTS', getdate()
         END

Morton,

Thanks for the input, but if I change from "f.puts s" to "f s" there
is an error:
NoMethodError: undefined method `f' for main:Object

Where can I find documentation on Ruby? I can't find anything on the
puts method of the File class, or what method I could use to direct
the string "s" to the file object.

Lars

Lars Zeb wrote:

I expected it was something like the following for each input line:
IF EXISTS (SELECT * FROM Sic WHERE Code = '3291')
      BEGIN
        UPDATE Sic
               SET Descr = 'ABRASIVE PRODUCTS'
               WHERE Code = '3291'
            END
         ELSE
            BEGIN
               INSERT INTO Sic
            SELECT '3291', 'ABRASIVE PRODUCTS', getdate()
         END

Is there no way to test what the return value of a function is? What's
the return value of the following function:

def sayhi
   puts "hello"
end

···

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

You should remove the puts in the get_sql function, not the f.puts call.

···

On [Wed, 30.01.2008 23:59], Lars Zeb wrote:

Morton,

Thanks for the input, but if I change from "f.puts s" to "f s" there
is an error:
NoMethodError: undefined method `f' for main:Object

Where can I find documentation on Ruby? I can't find anything on the
puts method of the File class, or what method I could use to direct
the string "s" to the file object.

Lars

--
Dominik Honnef

Concepts you need to explore:

1) What's the return value of the following method:

def g
  return 10
end

Can you write some code that proves what the return value is?

2) What's the return value of the following method:

def g
  20
end

Can you write some code that proves what the return value is?

2) What's the return value of g():

def f
  return 10
end

def g
  return f
end

3) What's the return value of g():

def f
  return 10
end

def g
  f
end

···

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

Perfect, Dominik, it works!

···

On Jan 30, 8:38 am, Dominik Honnef <domini...@gmx.net> wrote:

7stud, thanks for the help. I hope this is what you're looking for:
class SicCode
   def initialize(line)
      split_to_columns(line)
   end

   def split_to_columns(line)
      a = line.split(/\s+/)
      @sic = a[0]
      @descr = a.last(a.length - 1 ).join(" ")
   end

   def get_sql
      puts %Q{IF EXISTS (SELECT * FROM Sic WHERE Code = '#@sic')
      BEGIN
        UPDATE Sic
               SET Descr = '#@descr'
               WHERE Code = '#@sic'
            END
      ELSE
      BEGIN
  INSERT INTO Sic
  SELECT '#@sic', '#@descr', getdate()
      END
      }
   end
end

irb(main):069:0> line="3291 ABRASIVE PRODUCTS"
=> "3291 ABRASIVE PRODUCTS"
irb(main):070:0> puts SicCode.new(line).get_sql
IF EXISTS (SELECT * FROM Sic WHERE Code = '3291')
      BEGIN
        UPDATE Sic
               SET Descr = 'ABRASIVE PRODUCTS'
               WHERE Code = '3291'
            END
      ELSE
      BEGIN
INSERT INTO Sic
SELECT '3291', 'ABRASIVE PRODUCTS', getdate()
      END

nil
=> nil

···

On Jan 29, 9:43 pm, 7stud -- <bbxx789_0...@yahoo.com> wrote: