Usually this is useful for “self-calling” scripts like in this notorious example
The good script with embedded code should not use ugly escape sequences , no temp files and redundant output. Is it possible to be done with Ruby?
Usually this is useful for “self-calling” scripts like in this notorious example
The good script with embedded code should not use ugly escape sequences , no temp files and redundant output. Is it possible to be done with Ruby?
Yes with some hacks.Here’s an example ( file should be with .bat
extension ):
@break #^
=begin
@echo off
echo BATCH: Hello world!
ruby "%~f0" %*
exit /b 0
=end
puts 'RUBY: Hello world!'
Output will be:
BATCH: Hello world!
RUBY: Hello world!
Here’s the explanation.
For Ruby @break #^
will declare an instance variable break and will end the line with a comment.On the next line it will start a multi line comment where the batch code will be placed.
Cmd.exe on the other hand will execute silently the break command (because if the @ symbol) and because break command do nothing (it is and old dos command left only for backward compatibility) it will have no effect.The ending carret (it escapes the special symbols in batch) will escape the new line and first two lines will be taken for one. After the batch part is done we can close the Ruby comment and put the code.
Here can be seen few more examples of embedded code in batch (Python,PHP and so on).
This is another hack, IMHO a bit easier to understand as it does not depend on line continuation, block level comments and a CMD statement which is there only for backwards compatibility.
The main thing is, that the bat file also must be a syntactically valid ruby file. Within this ruby-file we need to embed the CMD syntax. For this we need to create an island of code which is transparent to ruby:
.
@rem = %Q{
@echo off
echo BATCH: Hello world!
ruby "%~f0" %*
exit /b %ERRORLEVEL%
}
# ruby code starts here
puts %Q{RUBY: Hello world! #{ARGV}}