Note, unless otherwise noted, all methods defined in S4tUtils are both module functions and instance functions.
Ask the question contained in the question_lines, prompt, and wait for an answer. If the stripped value read from STDIN is empty, use the default_answer.
# File lib/s4t-utils/command-line.rb, line 8 def ask(default_answer, *question_lines) puts question_lines print "[#{default_answer}] => " answer = STDIN.readline.strip answer = default_answer.to_s if answer == '' answer end
Run the block, capturing output to $stderr in a string. That string is the method’s return value.
# File lib/s4t-utils/capturing-globals.rb, line 9 def capturing_stderr old_stderr = $stderr new_stderr = StringIO.new begin $stderr = new_stderr yield ensure $stderr = old_stderr end new_stderr.string end
Run the block, capturing output to $stdout in a string. That string is the method’s return value.
Note: this assigns to $stdout, which is deprecated in favor of $stdout.reopen. However, reopen can’t take a StringIO as an argument.
# File lib/s4t-utils/capturing-globals.rb, line 27 def capturing_stdout new_stdout = StringIO.new $stdout = new_stdout begin yield ensure $stdout = STDOUT end new_stdout.string end
Run the block with the given file (named by a string) deleted before and after.
# File lib/s4t-utils/capturing-globals.rb, line 70 def erasing_local_config_file(file) with_home_right_here { begin File.delete(file) if File.exist?(file) yield ensure File.delete(file) if File.exist?(file) end } end
Use connector to join array into a human-friendly list.
friendly_list("or", [1]) => "'1'" friendly_list("or"), [1, 2] => "'1' or '2'" friendly_list("or"), [1, 2, 3] => "'1', '2', or '3'"
# File lib/s4t-utils/friendly-format.rb, line 15 def friendly_list(connector, array) quoted = array.collect { | elt | "'" + elt.to_s + "'" } case array.length when 0 "" when 1 quoted[0] when 2 quoted[0] + " #{connector} " + quoted[1] else quoted[0...-1].join(", ") + ", #{connector} #{quoted.last}" end end
A way of putting debugging statements in code that requires less typing
than puts.
pi [1, 2, 3], 'input' # => 'input: [1, 2, 3]
The arg is printed using inspect. If leader
isn’t given, nothing is printed before arg. leader can
be a string or symbol.
pi returns its arg, which is occasionally useful for sticking debugging into the middle of complicated expressions.
# File lib/s4t-utils/hacks.rb, line 28 def pi(arg, leader=nil) leader = leader.to_s if leader leader = (leader == nil) ? '' : leader + ': ' prog1(arg) { puts leader + arg.inspect } end
The return value of prog1 is the retval. Before that’s returned, though, the retval is yielded to the block. This method is an alternative to stashing a value in a temporary, fiddling around, then returning the temporary. Here’s an example:
prog1(1+1) { | s | puts "Sum is #{s}."} # => 2
The name “prog1” is ancient Lisp jargon.
# File lib/s4t-utils/hacks.rb, line 13 def prog1(retval) yield(retval) retval end
Produces a version of a string that can be typed after a : (Can also be safely given at a command-line prompt.)
# File lib/s4t-utils/friendly-format.rb, line 31 def symbol_safe_name(name) name.to_s.gsub(/\W/, '') end
A StandardError is thrown if the fact the user claims is true is actually false. The block is called to provide the exception message.
# File lib/s4t-utils/claims.rb, line 8 def user_claims(fact, &block) user_is_bewildered(block.call) unless fact end
A StandardError is thrown if the fact the user disputes is nevertheless true. The block is called to provide the exception message.
# File lib/s4t-utils/claims.rb, line 15 def user_disputes(fact, &block) user_claims(!fact, &block) end
An unconditional claim that the user is bewildered by something that should not have happened. Most usually, it’s that the code should never have gotten to this point.
# File lib/s4t-utils/claims.rb, line 23 def user_is_bewildered(msg = "How could this point be reached?") raise StandardError.new(msg) end
Run the block. During execution, ARGV’s is set as if the script had been executed with string as its argument list. If the block tries to exit, #with_command_args will instead throw a StandardError.
# File lib/s4t-utils/capturing-globals.rb, line 96 def with_command_args(string) begin old_argv = ARGV.dup ARGV.replace(string.split) yield rescue SystemExit => ex replacement = StandardError.new(ex.message) replacement.set_backtrace(ex.backtrace) raise replacement ensure ARGV.replace(old_argv) end end
Run the block, replacing the values of environment variables with the values given in the hash settings. The environment variables are restored when the method returns.
# File lib/s4t-utils/capturing-globals.rb, line 41 def with_environment_vars(settings) begin old = {} settings.each { | key, value | old[key] = ENV[key] ENV[key] = value } yield ensure settings.each_key { | key | ENV[key] = old[key] } end end
Run the block with the HOME environment variable set to the current working directory.
# File lib/s4t-utils/capturing-globals.rb, line 58 def with_home_right_here begin old_home = ENV['HOME'] ENV['HOME'] = '.' yield ensure ENV['HOME'] = old_home end end
Run the block. During the execution, the contents of file (named by a string) is replaced with contents.
# File lib/s4t-utils/capturing-globals.rb, line 83 def with_local_config_file(file, contents) erasing_local_config_file(file) do File.open(file, 'w') do | io | io.puts(contents.to_s) end yield end end
Typically used to wrap the execution of an entire script. If an exception is thrown, a terse message is printed (to $stderr) instead of a stack dump. The message printed is gotten from the exception.
# File lib/s4t-utils/error-handling.rb, line 9 def with_pleasant_exceptions yield rescue SystemExit raise rescue Exception => ex $stderr.puts(ex.message) end
# File lib/s4t-utils/capturing-globals.rb, line 110 def with_stdin(string) old_stdin = $stdin $stdin = StringIO.new(string) yield ensure $stdin = old_stdin end
#with_pleasant_exceptions swallows the stack trace, which you want to see during debugging. The easy way to see it is to add ‘out’ to that message, producing this one. To reduce the chance you’ll forget to make exceptions pleasant again, a note that exceptions are turned off is always printed to $stderr.
# File lib/s4t-utils/error-handling.rb, line 22 def without_pleasant_exceptions $stderr.puts "Note: exception handling turned off." yield end
If the given file lives as a script inside a typical Ruby development structure, put ../lib at the front of the path. That includes files from there in preference to old gems lying around.
# File lib/s4t-utils/os.rb, line 47 def set_script_lib_path(given) path = File.expand_path(given) p = lambda { | x | File.join(File.dirname(path), '..', x) } l = p['lib'] t = p['test'] s = p['setup.rb'] $:.unshift(l) if File.exists?(l) && File.exists?(t) && File.exists?(s) end
Find and set the paths a test needs to run, given the normal Ruby directory structure. given is something below the test directory. PACKAGE_ROOT becomes the root of the structure. PACKAGE_ROOT/lib and PACKAGE_ROOT itself are put on the front of the path (the latter is so that tests can require ‘test/something’.
# File lib/s4t-utils/os.rb, line 33 def set_test_paths(given) return if S4tUtils.const_defined?("PACKAGE_ROOT") path = File.expand_path(given) i = path.index("/test/") S4tUtils.const_set("PACKAGE_ROOT", path[0...i]) $:.unshift("#{PACKAGE_ROOT}/lib") $:.unshift("#{PACKAGE_ROOT}") end