Ruby unexpected $end, expecting keyword_end - ruby

I get the following error from my code.
ruby -w search.rub search.rub:19: warning: mismatched indentations at 'end' with 'case' at 12 search.rub:62: syntax error, unexpected $end, expecting keyword_end
I have a feeling that it has something to do with all the ends.
#!/usr/bin/ruby
num_line = 0
NumDiccionario = 1
def checkPassword (pass)
print pass, "\t"
system("bitcoind", "walletpassphrase", pass, "20")
case $?.exitstatus
when 0
puts "You found it!#{pass}"
File.open('password.txt', 'w') do |file|
file.puts phrase + "\n"
end
exit 0
end
str_num_line = "0"
File.open('lastLine.txt', 'r') do |file2|
str_num_line = file2.gets
end
if (str_num_line.to_i > 0 )
print "Last searching stopped at line " + str_num_line + "\n"
STDOUT.flush
print "Continue from here? y/n:"
resp = gets.chomp
if (resp == "y")
num_line =str_num_line.to_i
end
end

def checkPassword (pass)
print pass, "\t"
system("bitcoind", "walletpassphrase", pass, "20")
case $?.exitstatus
when 0
puts "You found it!#{pass}"
File.open('password.txt', 'w') do |file|
file.puts phrase + "\n"
end
end
exit 0
end

Related

opening certain files from a directory using Ruby

I am facing a certain problem while trying to open files from a directory ( the directory is provided on the command line )
My code is as follows:
require 'optparse'
OptionParser.new do |opts|
opts.banner = "Usage: rubyfile.rb [options]"
options[:c] = ""
opts.on( '-c', '--dir DILE', "Specify Directory with input files" ) do |e|
options[:c] = e
end
options[:o] = ""
opts.on( '-o', '--dir DILE', "Specify Output file" ) do |f|
options[:c] = f
end
end.parse!
out_file = File.open( options[:o], "a" )
dir_open = Dir.open( options[:c] )
Dir.foreach(dir_open) do | in_file |
next if File.directory? in_file
if( in_file.include? ".txt" )
input_file = File.open( in_file, "r" )
File.foreach(input_file).with_index do | line, line_s |
puts line
end
end
end
If I try to print out the file names using puts in_file, it works. But when I try to open the file and dump out its contents, it does not.
I know I am missing something here not able to pinpoint what it is though.
With this chunk right here:
input_file = File.open( in_file, "r" )
File.foreach(input_file).with_index do | line, line_s |
puts line
end
You could instead write File.readlines(in_file).each { |f| puts f }
File.readlines will return an array where each element is a line of the text.

Remove a string from a Ruby file when it matches a regex

I'm writing a little script in Ruby that removes comments from Ruby files:
#!/usr/bin/ruby
def uncomment(file)
File.readlines(file).each do |line|
if line =~ /(^\s*#|^\t*#)(?!\!).*/
puts line + " ==> this is a comment"
#todo: remove line from the file
end
end
end
puts "Fetching all files in current directory and uncommenting them"
# fetching all files
files = Dir.glob("**/**.rb")
# parsing each file
files.each do |file|
#fetching each line of the current file
uncomment file
end
I am stuck on how to remove these lines that match the regex in the #todo section, it would be great if someone could help!
change:
def uncomment(file)
File.readlines(file).each do |line|
if line =~ /#(?!\!).+/
puts line + " ==> this is a comment"
#todo: remove line from the file
end
end
end
to:
def uncomment(file)
accepted_content = File.readlines(file).reject { |line| line =~ /#(?!\!).+/ }
File.open(file, "w") { |f| accepted_content.each { |line| f.puts line } }
end
You would be reading the accepted lines into an array(accepted_content), and writing back that array into the file
I would do this by creating a temporary file:
open('tmp', 'w') do |tmp|
File.open(file).each do |line|
tmp << line unless line =~ /#(?!\!).+/
end
end
File.rename('tmp', file)

Ruby cannot open file ( Errno::ENOENT ) but the same path can be opened from IRB

I have a simple Ruby script that is building a list of files from an array of strings, so I have a method a bit like this:
def initialize( rootpath, name )
#content = ""
intermission = ""
if ( ! (rootpath[-1] == "/" || name[0] == "/" ))
intermission="/"
end
#path= "#{rootpath}#{intermission}#{name}"
print "Open JavascriptFile from #{#path}"
if (! File.exists? #path)
print "File does not exist!"
end
File.open( #path ).each do |line|
#content << line
end
end
This is called along the lines of:
files= ['alice.js', 'bob.js', 'claire.js', 'dave.js']
basepath= "/home/glenatron/projects/myJSProject/"
files.each do |filename|
myLoader.new( basepath, filename )
end
When I load in my classes from IRB and run this I get:
Open JavascriptFile from /home/glenatron/projects/myJSProject/alice.js
File does not exist!
Errno::ENOENT: No such file or directory - /home/glenatron/projects/myJSProject/alice.js
As I understand it, this means that the file does not exist.
However not only does the file definitely exist, in IRB I can paste the exact same path and see it's content - a simple File.open("/home/glenatron/projects/myJSProject/alice.js").each { | line | print line } reveals the complete content of the file. So why can I do this from a direct command line request and not from my Ruby class? Is it trying to read a local path instead of the full path I am passing it?
Guard the File.open .. lines with else block:
if (! File.exists? #path)
print "File does not exist!"
else # <---
File.open( #path ).each do |line|
#content << line
end
end # <----
or return earlier in the if block:
if (! File.exists? #path)
print "File does not exist!"
return
endif
Otherwise, the code always try to open the file, even if it does not exist.
Use File::join to join the path components:
File.join("/home/glenatron/projects/myJSProject/", "alice.js")
# => "/home/glenatron/projects/myJSProject/alice.js"
File.join("/home/glenatron/projects/myJSProject", "alice.js")
# => "/home/glenatron/projects/myJSProject/alice.js"
Edit to bring the solution ( in the comments ) into the answer:
To find the exact path, use p #path - this revealed that the path that was trying to open looked like this when it failed: /home/glenatron/projects/myJSProject/alice.js\r which was causing the problem. A simple #path.strip! resolved it once this was clear.
From your code shown in the question,
looks like an end instead of an else, e.g.
if (! File.exists? #path)
print "File does not exist!"
end # <------------ This wasn't valid
File.open( #path ).each do |line|
#content << line
end
end
should be
if (! File.exists? #path)
print "File does not exist!"
else
File.open( #path ).each do |line|
#content << line
end # THIS end is valid as it ends a `.each` block
end

What's wrong with my array initialization in ruby?

Why is this a syntax error in ruby?
#!/usr/bin/ruby
servers = [
"xyz1-3-l"
, "xyz1-2-l"
, "dws-zxy-l"
, "abcl"
]
hostname_input = ARGV[0]
hostname = hostname_input.gsub( /.example.com/, "" )
servers.each do |server|
if hostname == server then
puts "that's the one"
break
end
end
... when I execute this script I get this output ...
$ ./test.rb abc1
./test.rb:5: syntax error, unexpected ',', expecting ']'
, "xyz1-2-l"
^
./test.rb:6: syntax error, unexpected ',', expecting $end
, "dws-zxy-l"
^
... if I simply put everything on the same line its ok ...
$ cat test.rb
#!/usr/bin/ruby
servers = [ "xyz1-3-l" , "xyz1-2-l" , "dws-zxy-l" , "abcl" ]
hostname_input = ARGV[0]
hostname = hostname_input.gsub( /.example.com/, "" )
servers.each do |server|
if hostname == server then
puts "that's the one"
break
end
end
$ ./test.rb dws-zxy-l
that's the one
Look ma, no commas (or quotes):
servers = %W[
xyz1-3-l
xyz1-2-l
dws-zxy-l
abcl
]
# => ["xyz1-3-l", "xyz1-2-l", "dws-zxy-l", "abcl"]
Newlines are significant in Ruby. You need to put the comma at the end of the line or use a backslash before your newline to indicate that the line is continuing (of course, in that case, what's the point in moving the comma to the next line?).

How do I handle a missing mandatory argument in Ruby OptionParser?

In OptionParser I can make an option mandatory, but if I leave out that value it will take the name of any following option as the value, screwing up the rest of the command line parsing.
Here is a test case that echoes the values of the options:
$ ./test_case.rb --input foo --output bar
output bar
input foo
Now leave out the value for the first option:
$ ./test_case.rb --input --output bar
input --output
Is there some way to prevent it taking another option name as a value?
Thanks!
Here is the test case code:
#!/usr/bin/env ruby
require 'optparse'
files = Hash.new
option_parser = OptionParser.new do |opts|
opts.on('-i', '--input FILENAME', 'Input filename - required') do |filename|
files[:input] = filename
end
opts.on('-o', '--output FILENAME', 'Output filename - required') do |filename|
files[:output] = filename
end
end
begin
option_parser.parse!(ARGV)
rescue OptionParser::ParseError
$stderr.print "Error: " + $! + "\n"
exit
end
files.keys.each do |key|
print "#{key} #{files[key]}\n"
end
What you want to do is not a good idea. What if you really have a file named "--output"? This is a perfectly valid filename on Unix. Every Unix program's option parsing works the way the ruby one is doing, so you shouldn't change it, because then your program will be arbitrarily different from everything else, which is confusing and violates the "principle of least surprise."
The real question is: why are you having this problem in the first place? Perhaps you're running your program from another program, and the parent program is providing a blank filename as the parameter to --input, which makes it see --output as the parameter to --input. You can work around this by always quoting the filenames you pass on the command line:
./test_case.rb --input "" --output "bar"
Then --input will be blank, and that's easy to detect.
Also note that if --input is set to --output (and --output is not a real file) you can just try to open the --input file. If it fails, print a message like:
can't open input file: --output: file not found
And that should make it clear to the user what they did wrong.
try this:
opts.on('-i', '--input FILENAME', 'Input filename - required') do |filename|
files[:input] = filename
end
opts.on('-o', '--output FILENAME', 'Output filename - required') do |filename|
files[:output] = filename
end
opts.on("-h", "--help", "Show this message") do
puts opts
exit
end
begin
ARGV << "-h" if ARGV.size != 2
option_parser.parse!(ARGV)
rescue OptionParser::ParseError
$stderr.print "Error: " + $! + "\n"
exit
end
In this case, the mandatory --output option is missing, so do this after calling parse!:
unless files[:input] && files[:output]
$stderr.puts "Error: you must specify both --input and --output options."
exit 1
end
OK - this works - the regular expression in the on() call allows any string as long as it doesn't start with a '-'
If I don't pass an argument to --input and there is another option downstream then it will take that option key as the argument to --input. (e.g. --input --output). The regexp catches that and then I check the error message. If the argument it reports starts with '-' I output the correct error message, namely that there is a missing argument. Not pretty but it seems to work.
Here is my working test case:
#!/usr/bin/env ruby
require 'optparse'
files = Hash.new
option_parser = OptionParser.new do |opts|
opts.on('-i FILENAME', '--input FILENAME', /\A[^\-]+/, 'Input filename - required') do |filename|
files[:input] = filename
end
opts.on('-o FILENAME', '--output FILENAME', /\A[^\-]+/, 'Output filename - required') do |filename|
files[:output] = filename
end
end
begin
option_parser.parse!(ARGV)
rescue OptionParser::ParseError
if $!.to_s =~ /invalid\s+argument\:\s+(\-\-\S+)\s+\-/
$stderr.print "Error: missing argument: #{$1}\n"
else
$stderr.print "Error: " + $! + "\n"
end
exit
end
files.keys.each do |key|
print "#{key} #{files[key]}\n"
end

Resources