P
Peter Vanderhaden
I wrote a script that gets user input like this:
$stdout.print "Do you want to change something else? (y/n): "
$changeSE = gets.chomp
if $changeSE =~ /^y/
changeSomethingElse
end
After the prompt is printed, the script waits for the user to enter yes
or no via stdinput. The script was written in a procedural format as
opposed to OO. (I did that only because I'm in the process of learning
OO, and needed the script asap.) I decided to rewrite the script using
OO. Unfortunately, this part of the script doesn't work anymore. The
prompt prints, then the script keeps going on its merry way. I've
included the source for the script below. Can anyone (or everyone) see
what I'm not doing correctly? If so, I'd appreciate it if you could
explain how to correct the problem. I'd be extremely grateful for any
and all comments and assistance.
PV
1 #!/usr/bin/ruby
2 #
3 # fix1.rb - Fix common unitization file errors.
4 # 1. Remove header line.
5 # 2. Populate vendor label field with "NULL".
6 # 3. Change .TIF extension to lower case.
7 #
8 class Record
9
10 # Constructor.
11 def initialize (record_string)
12 @record = record_string
13 end
14
15 # Populates the volume label.
16 # regex: Start at the beginning of the line, match
17 # all non-comma characters, followed by 2 commas.
18 def fix_volume_label
19 # @record.sub!(/\d,,/,',NULL,')
20 @record.sub!(/^([^,]*),,/, '\1,NULL,')
21 end
22
23 # Change file extension to lowercase.
24 def fix_extension_case
25 @record.sub!('.TIF','.tif')
26 end
27
28 # Allow user to do a generic fix.
29 def changeSomethingElse
30 @record.sub!(before,after)
31 end
32
33 # Returns fixed record as a string
34 def to_str
35 @record
36 end
37
38 end
39
40 # Main thread of execution.
41 class FixOpt
42
43 def initialize
44
45 @ARGV = $* # list of arguments passed to the
script
46 @header_regex = /BegBates,Volume,Path/
47
48 @in_file = nil
49 # @out_file = nil
50 unless arguments_valid? @ARGV
51 usage
52 exit -1
53 end
54
55 # Does user want to change something else?
56 def checkChange
57 puts "Do you want to change something else (y/N): "
58 changeIt = gets
59 if changeIt =~ /^[yY]/
60 puts "Enter string to change: "
61 before = gets.chomp
62 puts "Enter new string: "
63 after = gets.chomp
64 puts "Global change? (N/y): "
65 global = gets.chomp
66 end
67 end # End checkChange method.
68
69 begin
70 @in_file = File.new @ARGV[0], "r"
71 rescue IOError
72 @in_file.close
73 puts "Error opening input file, terminating"
74 exit -1
75 end
76
77 end # End initialize method.
78
79 # Runs the program - the [C]ontroller portion of the MVC pattern.
80 def run
81 begin
82 checkChange
83 @in_file.each do |record_line|
84 next if record_line =~ @header_regex
85 record = Record.new(record_line)
86 record.fix_volume_label
87 record.fix_extension_case
88 if changeIt =~ /^[yY]/
89 record.changeSomethingElse
90 end
91 puts record.to_str
92 end
93 rescue IOError
94 @in_file.close
95 puts "Error reading from input file, terminating"
96 exit -1
97 end
98 @in_file.close
99 exit 0 # success!
100 end
101
102 # these methods are marked rivate becuase they are never to be
called
103 # from anywhere outside of the class itself.
104 rivate
105
106 # Validates command line arguments.
107 def arguments_valid? (argv)
108 # readable assumes the file exists, but doesn't check for it.
109 # File.stat(ARGV[0]).readable?
110 # Returns true if the named file exists and is a regular file.
111 File.file?(ARGV[0])
112 end
113
114 # Prints the usage message
115 def usage
116 puts
117 puts "Invalid filename entered: #{ARGV[0]}"
118 puts "Syntax: fix1.rb <filename>"
119 puts
120 end
121
122 end
123 fix_opt = FixOpt.new
124 fix_opt.run
If I use gets, the script just prints the prompt and seems to end.
If I use gets.chomp I get the following error:
$ ruby d:/scripts/ruby/fix1.rb 99999.opt
Do you want to change something else (y/N):
d:/scripts/ruby/fix1.rb:58:in `checkChange': private method `chomp'
called for nil:NilClass (NoMethodEr
ror)
from d:/scripts/ruby/fix1.rb:82:in `run'
from d:/scripts/ruby/fix1.rb:124
$stdout.print "Do you want to change something else? (y/n): "
$changeSE = gets.chomp
if $changeSE =~ /^y/
changeSomethingElse
end
After the prompt is printed, the script waits for the user to enter yes
or no via stdinput. The script was written in a procedural format as
opposed to OO. (I did that only because I'm in the process of learning
OO, and needed the script asap.) I decided to rewrite the script using
OO. Unfortunately, this part of the script doesn't work anymore. The
prompt prints, then the script keeps going on its merry way. I've
included the source for the script below. Can anyone (or everyone) see
what I'm not doing correctly? If so, I'd appreciate it if you could
explain how to correct the problem. I'd be extremely grateful for any
and all comments and assistance.
PV
1 #!/usr/bin/ruby
2 #
3 # fix1.rb - Fix common unitization file errors.
4 # 1. Remove header line.
5 # 2. Populate vendor label field with "NULL".
6 # 3. Change .TIF extension to lower case.
7 #
8 class Record
9
10 # Constructor.
11 def initialize (record_string)
12 @record = record_string
13 end
14
15 # Populates the volume label.
16 # regex: Start at the beginning of the line, match
17 # all non-comma characters, followed by 2 commas.
18 def fix_volume_label
19 # @record.sub!(/\d,,/,',NULL,')
20 @record.sub!(/^([^,]*),,/, '\1,NULL,')
21 end
22
23 # Change file extension to lowercase.
24 def fix_extension_case
25 @record.sub!('.TIF','.tif')
26 end
27
28 # Allow user to do a generic fix.
29 def changeSomethingElse
30 @record.sub!(before,after)
31 end
32
33 # Returns fixed record as a string
34 def to_str
35 @record
36 end
37
38 end
39
40 # Main thread of execution.
41 class FixOpt
42
43 def initialize
44
45 @ARGV = $* # list of arguments passed to the
script
46 @header_regex = /BegBates,Volume,Path/
47
48 @in_file = nil
49 # @out_file = nil
50 unless arguments_valid? @ARGV
51 usage
52 exit -1
53 end
54
55 # Does user want to change something else?
56 def checkChange
57 puts "Do you want to change something else (y/N): "
58 changeIt = gets
59 if changeIt =~ /^[yY]/
60 puts "Enter string to change: "
61 before = gets.chomp
62 puts "Enter new string: "
63 after = gets.chomp
64 puts "Global change? (N/y): "
65 global = gets.chomp
66 end
67 end # End checkChange method.
68
69 begin
70 @in_file = File.new @ARGV[0], "r"
71 rescue IOError
72 @in_file.close
73 puts "Error opening input file, terminating"
74 exit -1
75 end
76
77 end # End initialize method.
78
79 # Runs the program - the [C]ontroller portion of the MVC pattern.
80 def run
81 begin
82 checkChange
83 @in_file.each do |record_line|
84 next if record_line =~ @header_regex
85 record = Record.new(record_line)
86 record.fix_volume_label
87 record.fix_extension_case
88 if changeIt =~ /^[yY]/
89 record.changeSomethingElse
90 end
91 puts record.to_str
92 end
93 rescue IOError
94 @in_file.close
95 puts "Error reading from input file, terminating"
96 exit -1
97 end
98 @in_file.close
99 exit 0 # success!
100 end
101
102 # these methods are marked rivate becuase they are never to be
called
103 # from anywhere outside of the class itself.
104 rivate
105
106 # Validates command line arguments.
107 def arguments_valid? (argv)
108 # readable assumes the file exists, but doesn't check for it.
109 # File.stat(ARGV[0]).readable?
110 # Returns true if the named file exists and is a regular file.
111 File.file?(ARGV[0])
112 end
113
114 # Prints the usage message
115 def usage
116 puts
117 puts "Invalid filename entered: #{ARGV[0]}"
118 puts "Syntax: fix1.rb <filename>"
119 puts
120 end
121
122 end
123 fix_opt = FixOpt.new
124 fix_opt.run
If I use gets, the script just prints the prompt and seems to end.
If I use gets.chomp I get the following error:
$ ruby d:/scripts/ruby/fix1.rb 99999.opt
Do you want to change something else (y/N):
d:/scripts/ruby/fix1.rb:58:in `checkChange': private method `chomp'
called for nil:NilClass (NoMethodEr
ror)
from d:/scripts/ruby/fix1.rb:82:in `run'
from d:/scripts/ruby/fix1.rb:124