Get output from program into Ruby processing - ruby

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.

Related

Ruby - STDIN.read

I'm trying to read from a file, and because my more complex code doesn't work, I came back to basics to see whether it even reads properly.
My code:
MyParser.new(STDIN.read).run.lines.each do |line|
p line.chomp
end
I use
ruby program
(it's placed in a bin directory and I saved it without .rb )
Now program is waiting for me to write something. I type:
../examples/file.txt
and use CTRL + Z (I'm on Windows 10). It produces ^Z and I hit enter.
Now I have an error:
Invalid argument # rb_sysopen - ../examples/file.txt (Errno::EINVAL)
MyParser class and its whole logic works fine. I'll be grateful for any hints.
Without knowing, what your MyParser expect, it is hard to know, what you need.
But maybe this helps:
MyParser.new(STDIN.gets.strip).run.lines.each do |line|
p line.chomp
end
I would extend it by a message what you need:
puts "Please enter the filename"
STDOUT.flush
MyParser.new(STDIN.gets.strip).run.lines.each do |line|
p line.chomp
end
With STDOUT.flush the user gets the message, before STDIN.getswaits for a message.
In your case I would take a look on ARGV and call the program with:
ruby program ../examples/file.txt
Your program should then use:
MyParser.new(ARGV.first).run.lines.each do |line|
p line.chomp
end

Ruby script won't execute

New to Ruby. I have created a very simple script called "hello.rb":
name = "Frederik"
puts = "Hello #{name}"
It will not execute (there is no output) in my terminal when I run "ruby hello.rb". I have checked that my editor (atom) is creating EOL's using "cat -e hello.rb" as suggested by "mu is too short" here: Why won't my Ruby script execute?. What could be causing this? I have attached a screenshot for reference.
Thank you!
puts = "Hello #{name}"
You're assigning "Hello #{name}" to a variable named puts, not writing it to STDIO.
remove the assignment operator and your output should display normally.

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

Intercepting all puts and print statements from a Ruby program

I have legacy code, and rewriting this will take me a long while. Until then I need a solution that "works", even if it is ugly.
The main class of the code generates a long HTML string and stores this in an #instance variable.
Unfortunately, the larger framework also sometimes directly puts out something, through puts or print, and so can be used in a .cgi script.
I need to be able to capture all output from that framework, possibly filter or process it, before I send it to the user/visitor.
Is it possible to capture all puts and print statements from a Ruby script, and handle this gracefully?
In the final form, I will have to use puts and print anyway, but I need to sanitize some things there, possibly redirect, also optionally log output BEFORE I use puts/print.
Easy. By default puts and print output to the $stdout I/O channel. Reassign $stdout to a different file handle and output of those commands will go to the new channel.
Change where $stdout points.
File.open('spool.out', 'wb') do |fo|
$stdout = fo
puts 'hello world'
$stdout = STDOUT
end
Save that to a file and run it. You should see a file appear called "spool.out" containing "hello world".
It's not necessary to wrap everything in a File.open block. All that's important is you reassign $stdout to a file handle, then reset it later, so it could also be done like this:
$stdout = File.open('spool.out', 'wb')
puts 'hello world'
$stdout.close
$stdout = STDOUT
At startup, a Ruby script has access to a number of different global variables and constants: $stdout will be the same as STDOUT, and $stderr will be the same as STDERR.
See "Does Ruby use $stdout for writing the output of puts and return?" and "Putting the results of pp (or anything outputted to console) into a string" for more information.
You could redefine the print/puts function to add new functionality.
It could be done like so:
def print message
#do something, like editing the message and logging it
puts "Im here"
super "#{message}:edited version"
end
print "hello world"
Result:
->Im here
->hello world:edited version

Single Instance Ruby App?

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

Resources