lib/bio/command.rb in bio-1.4.2 vs lib/bio/command.rb in bio-1.4.3
- old
+ new
@@ -230,23 +230,41 @@
# ---
# *Arguments*:
# * (required) _cmd_: Array containing String objects
# * (optional) _options_: Hash
# *Returns*:: (undefined)
- def call_command_popen(cmd, options = {})
+ def call_command_popen(cmd, options = {}, &block)
if RUBY_VERSION >= "1.9.0" then
- # For Ruby 1.9 or later, using command line array with options.
- dir = options[:chdir]
- cmd = safe_command_line_array(cmd)
- if dir then
- cmd = cmd + [ { :chdir => dir } ]
+ if RUBY_ENGINE == 'jruby' then
+ _call_command_popen_jruby19(cmd, options, &block)
+ else
+ _call_command_popen_ruby19(cmd, options, &block)
end
- r = IO.popen(cmd, "r+") do |io|
- yield io
- end
- return r
+ else
+ _call_command_popen_ruby18(cmd, options, &block)
end
+ end
+
+ # This method is internally called from the call_command method.
+ # In normal case, use call_command, and do not call this method directly.
+ #
+ # Executes the program via IO.popen.
+ # A block must be given. An IO object is passed to the block.
+ #
+ # See the document of call_command for available options.
+ #
+ # The method is written for Ruby 1.8.
+ #
+ # In Ruby 1.8, although shell unsafe characters are escaped,
+ # if inescapable characters exists, it raises RuntimeError.
+ #
+ # ---
+ # *Arguments*:
+ # * (required) _cmd_: Array containing String objects
+ # * (optional) _options_: Hash
+ # *Returns*:: (undefined)
+ def _call_command_popen_ruby18(cmd, options = {})
# For Ruby 1.8, using command line string.
str = make_command_line(cmd)
# processing options
if dir = options[:chdir] then
if windows_platform?
@@ -265,14 +283,74 @@
IO.popen(str, "w+") do |io|
io.sync = true
yield io
end
end
+ private :_call_command_popen_ruby18
# This method is internally called from the call_command method.
# In normal case, use call_command, and do not call this method directly.
#
+ # Executes the program via IO.popen.
+ # A block must be given. An IO object is passed to the block.
+ #
+ # See the document of call_command for available options.
+ #
+ # The method can be run only on Ruby (MRI) 1.9 or later versions.
+ #
+ # ---
+ # *Arguments*:
+ # * (required) _cmd_: Array containing String objects
+ # * (optional) _options_: Hash
+ # *Returns*:: (undefined)
+ def _call_command_popen_ruby19(cmd, options = {})
+ # For Ruby 1.9 or later, using command line array with options.
+ dir = options[:chdir]
+ cmd = safe_command_line_array(cmd)
+ if dir then
+ cmd = cmd + [ { :chdir => dir } ]
+ end
+ r = IO.popen(cmd, "r+") do |io|
+ yield io
+ end
+ return r
+ end
+ private :_call_command_popen_ruby19
+
+ # This method is internally called from the call_command method.
+ # In normal case, use call_command, and do not call this method directly.
+ #
+ # Executes the program via IO.popen.
+ # A block must be given. An IO object is passed to the block.
+ #
+ # See the document of call_command for available options.
+ #
+ # The method is written for the workaround of the JRuby bugs:
+ # * {JRUBY-6195}[http://jira.codehaus.org/browse/JRUBY-6195] Process.spawn
+ # (and related methods) ignore option hash
+ # * {JRUBY-6818}[http://jira.codehaus.org/browse/JRUBY-6818] Kernel.exec,
+ # Process.spawn (and IO.popen etc.) raise error when program is an array
+ # containing two strings
+ # This method may be removed after the bugs are resolved.
+ #
+ # ---
+ # *Arguments*:
+ # * (required) _cmd_: Array containing String objects
+ # * (optional) _options_: Hash
+ # *Returns*:: (undefined)
+ def _call_command_popen_jruby19(cmd, options = {}, &block)
+ if !options.empty? or cmd.size == 1 then
+ _call_command_popen_ruby18(cmd, options, &block)
+ else
+ _call_command_popen_ruby19(cmd, options, &block)
+ end
+ end
+ private :_call_command_popen_jruby19
+
+ # This method is internally called from the call_command method.
+ # In normal case, use call_command, and do not call this method directly.
+ #
# Executes the program via fork (by using IO.popen("-")) and exec.
# A block must be given. An IO object is passed to the block.
#
# See the document of call_command for available options.
#
@@ -545,37 +623,41 @@
# is destroyed by GC.
#
# BioRuby library internal use only.
class Tmpdir
- # Returns finalizer object for Tmpdir class.
- # Internal use only. Users should not call this method directly.
- #
- # Acknowledgement: The essense of the code is taken from tempfile.rb
- # in Ruby 1.8.7.
+ # Internal use only. Users should not use this class directly.
#
- # ---
- # *Arguments*:
- # * (required) _data_: Array containing internal data
- # *Returns*:: Proc object
- def self.callback(data)
- pid = $$
- lambda {
- path, = *data
- if pid == $$
- $stderr.print "removing ", path, " ..." if $DEBUG
- if path and !path.empty? and
- File.directory?(path) and
- !File.symlink?(path) then
- Bio::Command.remove_entry_secure(path)
- $stderr.print "done\n" if $DEBUG
- else
- $stderr.print "skipped\n" if $DEBUG
- end
+ # Bio::Command::Tmpdir::Remover is a class to remove temporary
+ # directory.
+ #
+ # Acknowledgement: The essense of the code is taken from tempfile.rb
+ # in Ruby trunk (svn 34413) and in Ruby 1.8.7.
+ class Remover
+ # Internal use only. Users should not call this method.
+ def initialize(data)
+ @pid = $$
+ @data = data
+ end
+
+ # Internal use only. Users should not call this method.
+ def call(*args)
+ return if @pid != $$
+
+ path, = *@data
+
+ STDERR.print "removing ", path, "..." if $DEBUG
+ if path and !path.empty? and
+ File.directory?(path) and
+ !File.symlink?(path) then
+ Bio::Command.remove_entry_secure(path)
+ $stderr.print "done\n" if $DEBUG
+ else
+ $stderr.print "skipped\n" if $DEBUG
end
- }
- end
+ end
+ end #class Remover
# Creates a new Tmpdir object.
# The arguments are the same as Bio::Command.mktmpdir.
#
# ---
@@ -583,10 +665,10 @@
# * (optional) <em>prefix_suffix</em>: String (or Array)
# * (optional) <em>tmpdir</em>: String: temporary directory's path
# *Returns*:: Tmpdir object
def initialize(prefix_suffix = nil, tmpdir = nil)
@data = []
- @clean_proc = self.class.callback(@data)
+ @clean_proc = Remover.new(@data)
ObjectSpace.define_finalizer(self, @clean_proc)
@data.push(@path = Bio::Command.mktmpdir(prefix_suffix, tmpdir).freeze)
end
# Path to the temporay directory