newbie file write problem

L

Lars Zeb

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
 
7

7stud --

Lars said:
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.
 
Y

yermej

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 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.
 
L

Lars Zeb

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
 
7

7stud --

Lars said:
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.
 
L

Lars Zeb

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).
 
7

7stud --

Lars said:
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?
 
L

Lars Zeb

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
 
7

7stud --

Lars said:
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
 
7

7stud --

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
 
M

Morton Goldberg

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


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
 
L

Lars Zeb

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
 
L

Lars Zeb

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
 
D

Dominik Honnef

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
You should remove the puts in the get_sql function, not the f.puts call.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,241
Latest member
Lisa1997

Latest Threads

Top