Single Instance Ruby App? - ruby

If I've got a Ruby program, and I only want one instance of it to be able to run at a time, what are best[1] ways of accomplishing that? I've tried Googling but it thinks I'm looking for singleton-related information making it hard to find what I'm actually looking for.
[1] best= shortest, simplest, self-explanitory, doesn't require extra gems

From http://rosettacode.org/wiki/Determine_if_only_one_instance_is_running#Ruby
def main
puts "first instance"
sleep 20
puts :done
end
if $0 == __FILE__
if File.new(__FILE__).flock(File::LOCK_EX | File::LOCK_NB)
main
else
raise "another instance of this program is running"
end
end

Related

How to cancel evaluating a required Ruby file? (a.k.a. top-level return)

file1 requires file2, and I want to be able to cancel evaluating file2 under certain conditions without exiting the whole process.
# file1.rb
puts "In file 1"
require 'file2'
puts "Back in file 1"
# file2.rb
puts "In file 2"
# return if some_conditional
puts "Still in file 2"
When running file1, the output I want to see is:
In file 1
In file 2
Back in file 1
The goal is for Still in file 2 to never print, while Back in file 1 does print. Is there anything I can do in file2 to make this possible?
I can't use exit/exit!/abort here because Back in file 1 will never print. I could use raise/fail, but to do that I would have to change file1 and rescue the failed require. I'm hoping to find a way that doesn't involve altering file1.
UPDATE:
A "top-level return" feature has been added.
UPDATE:
A "top-level return" feature has been added.
ORIGINAL:
Commenter matt pointed out that Feature 4840, which would do exactly what I'm asking about, has been in discussion since June 2011. Further, the feature was still being discussed as late as November 2015 in core team meetings regarding new Ruby features.
There are a lot of difficulties involved in designing a feature like this; for a list of the pros and cons, I highly suggest checking out the discussions.
The proposed feature would allow exiting the required file while using any of the the following top-level statements:
if condition
return
end
while condition
# ...
return
end
begin
# ...
return
rescue
# ...
return
ensure
# ...
return
end
And it would not exit the required file in the following statements:
class Foo
return # LocalJumpError
end
def foo
return # returns from method, not from required file
end
proc do
return # LocalJumpError
end
x = -> { return } # returns as from lambda, not from required file
Since the feature remains unimplemented, I have awarded the bounty to steenslag for successfully solving the problem (as originally written) to the letter, if not the spirit.
Lines below __END__ will not be executed.
# file2.rb
puts "In file 2"
__END__
puts "Still in file 2" # Never gets called
I don't know of any official method for breaking out of required files, especially as there are several require methods (e.g., bundler monkey patches require)
The best solution I could come up with was using rubys throw-catch control flow. I'm not sure conditional you're using to determine if execute should return early, but this should be able to cope with most situations
# file1.rb
puts "In file 1"
catch(:done) do
require 'file2' end
puts "Back in file 1"
# file2.rb
puts "In file 2"
throw :done
puts "Still in file 2" # Never gets called
Is using a method possible ? It will still parse the method but won't get executed. Something like :
#file1.rb
puts "In file 1"
require 'file2'
puts "Back in file 1"
a_method
#file2.rb
puts "In file 2"
# <= A
def a_method
puts "Still in file 2"
end

How to use a conditional within a Ruby expect script

I'm playing with expect in Ruby but I'm a little lost as to how I can branch my code based on the behavior of a device I am logging into. How could I do say foo.run if I get the correct prompt below > but run foo.fail if I do not? Even further, how can I evaluate all of the text that comes back between entering the password and receiving the > prompt? Is there a way to look at all text that the device prints somehow?
def device_test(password)
$expect_verbose = true
PTY.spawn("ssh my-router") do |reader, writer, pid|
reader.expect("password:")
writer.puts(password)
reader.expect(">")
puts "logged in"
sleep(15)
end
end
It appears that the expect method can only look for a single pattern (unlike the Tcl expect library where you can look for multiple patterns simultaneously).
It looks like you'll have to pass a "timeout" parameter and check the return value:
if reader.expect(">", 2)
puts "foo.run"
else
# did not see ">" within 2 seconds
puts "foo.fail
end

Find path to file that required this one

I'll show an example of what I'm trying to do.
child.rb
require 'parent'
class Child < Parent
...
end
parent.rb
class Parent
puts __FILE__
...
end
running this (e.g. in IRB):
require 'child'
child=Child.new
returns this:
/path/to/parent.rb
but i'm really trying to get the file child.rb instead.
How can i do this without moving the puts __FILE__ in to the child class directly?
There is no way in Ruby to get what you are asking for. Perhaps if you explained why you want this—what you are trying to accomplish—then I (or someone else) could help you further. As it stands you seem to be asking an XY problem.
Although it's not always the "file that required me", you can use $0 in this case instead of __FILE__ to get "the root file that is running" in the case when you have done ruby parent.rb. Note that this will not work with IRB, however. (Inside IRB $0 is always "irb" or something equally unhelpful.)
Redefine require to output caller_locations.first.absolute_path before calling the original require.
you can use some backtrace method like caller_locations(1,1)[0].path or caller

Get output from program into Ruby processing

I am using the Ruby processing library.
I would like to pipe output from a program into my code. For example, echo "hello" | rp5 run receiver.rb.
In a normal program, I know I can accomplish this with
while $stdin.gets
puts $_
puts "Receiving!"
end
And I know that in processing, the program loops through the draw function continuously. So I tried this code, but it did not work, since it freezes on the line puts $stdin.gets. So I know it must be a problem with the pipes not matching up, so I'm going to try using named pipes so that there is no confusion.
def setup
puts "setting up"
end
def draw
puts "drawing"
puts $stdin
puts $stdin.gets
puts "after gets"
while $stdin.gets
puts $_
puts "Receiving!"
end
puts "done drawing"
end
Any suggestion would be appreciated. I'm running Ubuntu 12.04.
Yep, the name pipes worked. Check out this example to get you started and make sure you have the latest version of JRuby loaded.

How to read and process a file in Ruby with EventMachine

I am wondering if anybody figured out a way to process bigger (500Mb+) text files with EventMachine, where you actually need to access the individual lines.
I guess I found the answer, the only thing is messy is the read_chunk gets called in the after io.gets, and I am not sure why it works :)
require 'eventmachine'
def process_line(line)
puts line
end
EM.run do
io = File.open('query_profiles.csv')
read_chunk = proc do
if line = io.gets
process_line(line)
EM.next_tick(read_chunk)
else
EM.stop
end
end
EM.next_tick(read_chunk)
end

Resources