SciTE version is 2.25.
I have some ruby code to test it.
def foo
puts "hello"
sleep 5
puts "world"
end
puts foo
SciTE's output pane will show this:
>ruby scite.rb
And 5 seconds later print:
hello
world
>Exit code: 0
It's not correct and I remember the previous version SciTE is right. Why?
Try putting STDOUT.sync = true at the beginning of your program. I'm neither a Windows nor SciTE user, but I know that some of our students at Rubylearning had similar problems and apparently that was the fix (or manual calls to flush after outputting something).
Related
I'm new to ruby and this issue is bugging me for a while . Whenever i use gets to take user input , my gets statement is executed right after i run the file .I'm using git Bash to run my file.rb file ,
puts "some unnecessary text"
puts "Hello world"
puts "now you should input something"
x = gets.chomp
puts 36
puts "your input is " + x + " right?"
the program should print the first 3 lines before waiting for an input but it waits for the input right after i run it
$ruby file.rb
|
it waits for eternity unless I press enter . If i write something,
$ ruby file.rb
myInput
some unnecessary text
Hello world
now you should input something
36
your input is myInput right?
it runs okay . So I'm forced to write my input at the beginning .
It's not much of a problem right now but it'll cause a lot if headaches when i write bigger and more complex code . Any solutions ?
ps: It seems the problem only occurs with git Bash (windows) . Powershell works just fine .
It seems that the standard output is buffered.
Try to put at the beginning of the file (first two lines) old_sync = $stdout.sync $stdout.sync = true and a the end of the file (last line) $stdout.sync = old_sync.
The call to the IO#sync= method set the sync mode to true. This cause that all output is immediately flushed, at the end of the script we restore its value to its original old value, see Ruby documentation for details.
In summary:
old_sync = $stdout.sync # cache old value
$stdout.sync = true # set mode to true
# your scripting staff
$stdout.sync = old_sync # restore old value
If this trick works at least you know the reason for the weird behaviour. You can find some explanation also in this SO post.
This is just a sample method I have created for testing purpose using Ruby on Mac OSX 10.12 but I don't get the desired output: Can anyone suggest please? I tried getting the result using both paranthesis and without (). It doesn't even throw any error.
def hi
puts "Hello World"
End
hi
hi()
hi("Hello Matz")`
Try this:
def hi
puts "Hello World"
end
hi
hi()
And this:
def greet(greeting)
puts greeting
end
greet("Hello Matz")
Note that in this line:
hi("Hello Matz")`
you have a tick mark at the end, so that is an error:
1.rb:5: syntax error, unexpected tXSTRING_BEG, expecting end-of-input
It doesn't even throw any error.
Then you aren't running that program.
I suggest you open a Terminal window (Applications/Utilities/Terminal.app), and type in:
$ vimtutor
vim is a free computer programming editor that comes with your Mac. Do the tutorial and learn how to use vim. To run a ruby program, you enter your code into a file, then save it as, say, my_prog.rb. Then you need to give that file to ruby to execute it. You execute a ruby program like this:
$ ruby my_prog.rb
You can create a directory for all your ruby programs like this:
$ mkdir ruby_programs
$ cd ruby_programs
To create a new file inside that directory, use vim:
~/ruby_programs$ vi my_prog.rb
Once you are done typing in your code, save the file, which will put you back at the prompt in Terminal, then you can run your program:
~/ruby_programs$ ruby my_prog.rb
Once you get comfortable with vim, and you feel confident running your ruby programs, consider installing macvim with the vivid chalk color scheme:
It's nicer to look at than plain vim.
Try editing your file so that it reads:
def hi
puts "Hello World"
end
hi
Some important differences to note: def and end are both case-sensitive. The inside of the function definition is indented by two spaces. Since the function takes no arguments, no parentheses are necessary on the call to hi on line 4.
Depending on your filename, enter the command ruby FILENAME and you should see the output Hello World
Ruby keywords are case sensitive. Your code uses End and you probably wanted to use end to mark the end of the hi method.
Because End is not the same as end (and End is not a keyword), irb keeps waiting for input and treats the other three lines as part of the hi method. As far as it can tell, its definition is not complete until it reaches the end keyword (all non-capital letters.)
The correct way to define the method is:
def hi
puts "Hello World"
end
Then you can call it using either hi or hi().
Calling it as hi("Hello Matz") (or hi "Hello Matz") throws an ArgumentError exception with the message wrong number of arguments (given 1, expected 0) because it is called with one argument but the definition of method hi doesn't specify anything about arguments (by its definition, the method hi doesn't accept any argument).
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.
The ruby debugger does not halt on breakpoints I set in files different from the on the execution starts in. For example, consider these two files, foo.rb:
# foo.rb
class Foo
def bar
puts "baz"
end
end
and main.rb:
# main.rb
require './foo'
Foo.new.bar
I start debugging using ruby -r debug .\main.rb. Now, when I try to set a breakpoint on a specific line in another file using b ./foo.rb:4, I get the message Set breakpoint 1 at foo.rb:4, but when I cont, the program executes to the end, and the debugger never halts. However, if I break on a line in main.rb, e.g. b ./main.rb:3, or a method, e.g. b Foo.bar, the debugger halts as expected.
Why doesn't the debugger halt at breakpoints in files other than the main file?
Update: I have tried this with Ruby 1.9.3 on Windows 7 as well as OS X 10.8; it doesn't work in either environment.
I have also just realized that the debugger quits after the script has run till the end: I start debugging main.rb, use cont, then baz is printed on the console and I'm right back in the shell. Is this the expected behaviour, or might the debugger have crashed?
Wow, that is weird. Not sure if this helps, but maybe you could do this. Step over the require with next so that Foo is loaded then
b Foo:bar
that should at least break on bar
What is active_record doing to the signal processes under windows (I don't see this with the same versions on the mac) that causes it to behave so strangely? For instance:
require 'rubygems'
trap("INT"){puts "interrupted"}
puts __LINE__
sleep 5
require 'active_record'
trap("INT"){puts "interrupted again"}
puts __LINE__
sleep 5
When I run the above code (ruby 1.8.6, gem 1.3.1, activerecord 2.2.2,) I can hit ^C as many times as I like during the first sleep, but the first interrupt after the require of activerecord causes the script to terminate. In the above case, the trap still executes, it only fails to allow the program to continue. Usually.
Removing the second call to trap does not have any effect upon the behaviors.
The real annoyance is that in some conditions, the trap fails to execute at all. Considering that the whole point of doing this is to get my code to clean up after itself (remove its footprint in the database so the next guy sees a sane state,) this is a real problem. For instance:
require 'rubygems'
require 'active_record'
trap("INT"){puts "interrupted"}
puts __LINE__
gets
Pressing ^C after seeing the puts will not execute the trap at all.
I only see this problem after requiring active_record. Is there a workaround? I'd be curious to know if this is a bug or if there is an explanation of some sort. As I said, I have no issue with this on the mac - repeated ^Cs result in multiple executions of the trap proc.
thanks...
Considering that the whole point of doing this is to get my code to clean up after itself (remove its footprint in the database ...
Have you considered just using a database transaction? It seems like it would be a much easier way to solve the problem.
I saw a different pattern when trying to duplicate this problem:
puts "start"
trap("INT") { puts "interrupted" }
sleep 5
puts "end"
On Ubuntu (Ruby 1.8.6) this produces
start
interrupted
interrupted
(etc)
interrupted
end
So "interrupted" prints each time Crtl-C is pressed, until the 5 seconds are up. Under Windows (also Ruby 1.8.6), this produces:
start
interrupted
end
i.e. it prints "interrupted" once and then exits.
So it appears that while handling SIGINT Ruby exits the sleep routine and continues on to the next statement. My guess (hand-waving) is that this is somehow due to Ruby using green threads instead of native threads on Windows. Any experts please chime in here.
You could emulate the Unix-y behavior by restarting sleep in the handler:
puts "start"
trap("INT") do
puts "interrupted"
sleep 5
end
sleep 5
puts "end"
Unfortunately this resets the timer each time SIGINT is trapped, so it needs some hacking:
$interval = 5
def go_to_sleep(secs)
$started = Time.now
sleep secs
end
trap("INT") do
puts "interrupted"
time_to_sleep = [0,$interval - (Time.now - $started)].max
if time_to_sleep > 0
sleep time_to_sleep
end
end
puts "one"
go_to_sleep($interval)
puts "two"
go_to_sleep($interval)
puts "three"
go_to_sleep($interval)