Ruby on Shell
A handbook on using Ruby for shell scripting!
Introduction
Welcome to Ruby on Shell! This is a guide/handbook on using Ruby for shell scripting. This handbook will list most shell commands, and it's Ruby equivalent. This page is using the Ruby's document for version 3.2.2 as a referent. If you have questions or want to feedback, please open an issue.
Why not Bash?
Quote from Closh's README:
- Bash has obscure syntax for non-trivial operations and lots of WTF moments.
- It treats everything as text while we mostly need to manipulate structured information.
- It is a large codebase which makes it difficult to hack on it and try innovative ideas. Which is one of the reasons why the shell did not improve much in recent decades.
Quote from Replacing Bash Scripting with Python:
I do believe that for a program which deals primarily with starting processes
and connecting their inputs and outputs, as well as certain kinds of file
management tasks, the shell should still be the first candidate. A good
example might be setting up a server. I keep config files for my shell
environment in Git (like any sane person), and I use sh
for
all the setup. That's fine. In fact, it's great. Running some commands and
symlinking files is a usecase that fits perfectly to the strengths of the
shell.
I also have shell scripts for automating certain parts of my build, testing and publishing workflow for my programming, and I will probably continue to use such scripts for a long time.
Many people have rule about the length of their Bash scripts. It is oft repeated on the Internet that, "If your shell script gets to fifty lines, rewrite in another language," or something similar. The number of lines varies from 10 to 20 to 50 to 100. Among the Unix old guard, "another language" is basically always Perl.
This kind of rule isn't too bad. Length isn't the problem, but length can be a side-effect of complexity, and complexity is sort of the arch-enemy of Bash. I look for the use of certain features to be an indicator that it's time to consider a rewrite. (note that "rewrite" can mean moving certain parts of the logic into another language while still doing orchestration in Bash). These "warning signs are" listed in order of more to less serious.
-
If you ever need to type the characters
IFS=
, rewrite immediately. You're on the highway to Hell. -
If data is being stored in Bash arrays, either refactor so the data
can be streamed through pipelines or use a different language. As with
IFS
, it means you're entering the wild world of the shell's string splitting rules. That's not the world for you. -
If you find yourself using braced parameter expansion syntax,
${my_var}
, and anything is between those braces besides the name of your variable, it's a bad sign. For one, it means you might be using an array, and that's not good. If you're not using an array, it means you're using the shell's string manipulation capabilities. There are cases where this might be allowable (determining the basename of a file, for example), but the syntax for that kind of thing is very strange, and so many other languages supply better string manipulating tools. -
Dealing with process output in a loop is not a great idea. If you HAVE
to do it, the only right way is with
while IFS= read -r line
. Don't listen to anyone who tells you differently, ever. Always try to refactor this case as a one-liner with AWK or Perl, or write a script in another language to process the data and call it from Bash. If you have a loop like this, and you are starting any processes inside the loop, you will have major performance problems. This will eventually lead to refactoring with Bash built-ins. In the final stages, it results in madness and suicide. - Bash functions, while occasionally useful, can be a sign of trouble. All the variables are global by default. It also means there is enough complexity that you can't do it with a completely linear control flow. That's also not a good sign for Bash. A few Bash functions might be alright, but it's a warning sign.
- Conditional logic, while it can definitely be useful, is also a sign of increasing complexity. As with functions, using it doesn't mean you have to rewrite, but every time you write one, you should ask yourself the question as to whether the task you're doing isn't better suited to another language.
Finally, whenever you use a $
in Bash (parameter expansion),
you must use quotation marks. Always only ever use quotation marks.
Never forget. Never be lazy. This is a security hazard. As previously
mentioned, Bash is an injection honeypot. There are a few cases where
you don't need the quotation marks. They are the exceptions. Do not
learn them. Just use quotes all the time. It is always correct.
Why Ruby?
Quote from Idiosyncratic Ruby:
It is a language with a terrific community (welcoming and always questioning itself) and ecosystem (a lot of problems already solved), which is beautiful (focus on productivity), a little conservative (in the sense that it is easy to work with), and general purpose (a good choice in most cases).
Familiarity:
The Ruby's syntax is extremely similar to the established shell scripting languages. From it's semi-whitespace-significant style to it's keyword-base blocks syntax...
In Ruby everything is an object of some class, and every class have ton of powerful methods. Because of that, you could write a straightforward method chaining just like a pipeline in shell.
# Bash
echo 'zab rab oof' | rev | sed -e 's/bar/banana/g' | tr '[[:lower:]]' '[[:upper:]]' | cut -d ' ' -f 2 #=> "BANANA"
# Ruby
'zab rab oof'.reverse.gsub('bar', 'banana').upcase.split[1] #=> "BANANA"
Convenient:
Although Ruby in not a shell language, it can call shell command (with its syntax) inside Ruby just by wrapping it with backticks:
`ls` # List directory contents
bar = 'banana'
`echo foo #{bar}` #=> "foo banana\n"
`true && echo '!dlroW ,olleH' | rev` #=> "Hello, World!\n"
The more you understand Ruby, the shorter and nicer your code can be:
# Count lines of file:
File.open('path/to/file') { |file| file.read.split("\n").size }
File.open('path/to/file') { |file| file.read.lines.size }
File.open('path/to/file') { |file| file.readlines.size }
File.open('path/to/file') { _1.readlines.size }
File.read('path/to/file').lines.size
File.readlines('path/to/file').size
# Count the number of even bytes in a string:
'Hello, World!'.bytes.select { |number| number % 2 == 0 }.size
'Hello, World!'.bytes.select { |number| number.even? }.size
'Hello, World!'.bytes.select { _1.even? }.size
'Hello, World!'.bytes.select(&:even?).size
'Hello, World!'.bytes.count(&:even?)
It's Fun:
Ruby is a joy to read and write with. The language is elegantly designed to make the script we write in feel natural.
Ruby is also flexible, it gives you the freedom to write the code the
way you want. E.g: Instead of the keyword-base blocks syntax you can
write blocks in C-style { ... }
.
The language is so expressive, it's perfect for code-golfing or do some crazy tricks like in the TRIC contest.
Getting started
First, you need to learn the basic of Ruby. There are many ways to learn Ruby, but I found this tutorial to be the best one to introduce you to the languages:
If you prefer reading, The Odin Project is a great alternative.
Or if you come from other programming languages, Ruby From Other Languages is the quickest path to learn Ruby.
Next you can read Enhanced Shell Scripting with Ruby which is focused way more on using Ruby for shell scripting.
The Ruby document is a very organized and easy to digest resource. You can easily go through all the basic objects and those are methods to utilize the most out of the language power:
Some other useful resource: Idiosyncratic Ruby, Ruby Style Guide.
Ruby as interactive shell
Ruby is great for scripting but it's syntax is a bit strict for quick and frequent tasks.
The best way to use Ruby in the command-line is to bind irb
to a key like
Alt + R for example,
so you can quickly toggle between simple shell mode and Ruby scripting mode.
Add the keybind to your prefer interactive shell:
For Bash (~/.bashrc
):
bind -x '"\er":"irb"'
For Zsh (~/.zshrc
):
bindkey -s "\er" '^Qirb^J'
For Fish (~/.config/fish/config.fish
):
bind \er 'irb; commandline -f repaint'
Shell's Builtin Command
Shell's Basic
COMMAND #
Kernel#‘
(from ruby core)
`command` -> string
Returns the $stdout
output from running command
in a subshell; sets global variable $?
to the process status.
This method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Examples:
$ `date` # => "Wed Apr 9 08:56:30 CDT 2003\n"
$ `echo oops && exit 99` # => "oops\n"
$ $? # => #<Process::Status: pid 17088 exit 99>
$ $?.status # => 99>
The built-in syntax %x{...}
uses this method.
Kernel#system
(from ruby core)
system([env,] command... [,options], exception: false) -> true, false or nil
Executes command… in a subshell. command… is one of following forms.
This method has potential security vulnerabilities if called with untrusted input; see Command Injection.
commandline
:
command line string which is passed to the standard shell
cmdname, arg1, ...
:
command name and one or more arguments (no shell)
[cmdname, argv0], arg1, ...
:
command name, <tt>argv[0]</tt> and zero or more arguments (no shell)
system returns true
if the command gives zero exit status, false
for non zero exit status. Returns nil
if command execution fails. An error status is available in $?
.
If the exception: true
argument is passed, the method raises an exception instead of returning false
or nil
.
The arguments are processed in the same way as for Kernel#spawn.
The hash arguments, env and options, are same as #exec and #spawn. See Kernel#spawn for details.
system("echo *")
system("echo", "*")
produces:
config.h main.rb
*
Error handling:
system("cat nonexistent.txt")
# => false
system("catt nonexistent.txt")
# => nil
system("cat nonexistent.txt", exception: true)
# RuntimeError (Command failed with exit 1: cat)
system("catt nonexistent.txt", exception: true)
# Errno::ENOENT (No such file or directory - catt)
See Kernel#exec for the standard shell.
Kernel#system
print the result, whileKernel#`
returns the result as a string and print nothing.Kernel#`
it can be written as%x{ command }
(use it only when necessary).- You can use string interpolation (
#{ ... }
) insideKernel#`
:
foo = 'bar'
`echo #{foo}` #=> "bar\n"
You can read more on How to call shell commands from Ruby | Stack Overflow.
{ COMMANDS } #
begin some_methods end
or { some_methods }
in Ruby.
$(( expression )) let #
. source #
Kernel#require_relative
(from ruby core)
require_relative(file)
Ruby tries to load the library named string relative to the directory containing the requiring file. If the file does not exist a LoadError is raised. Returns true
if the file was loaded and false
if the file was already loaded before.
: true false #
Equivalent Ruby keyword: true false
TrueClass < Object
(from ruby core)
The global value true
is the only instance of class TrueClass and represents a logically true value in boolean expressions. The class provides operators allowing true
to be used in logical expressions.
Instance methods:
&
===
^
inspect
to_s
|
FalseClass < Object
(from ruby core)
The global value false
is the only instance of class FalseClass and represents a logically false value in boolean expressions. The class provides operators allowing false
to participate correctly in logical expressions.
Instance methods:
&
===
^
inspect
to_s
|
COMMAND1 && COMMAND2 #
method1 && method2
or object1 && object2
COMMAND1 || COMMAND2 #
method1 || method2
or object1 || object2
[ [[ test #
Kernel#test
(from ruby core)
test(cmd, file1 [, file2] ) -> obj
Uses the character cmd
to perform various tests on file1
(first table below) or on file1
and file2
(second table).
File tests on a single file:
Cmd Returns Meaning
"A" | Time | Last access time for file1
"b" | boolean | True if file1 is a block device
"c" | boolean | True if file1 is a character device
"C" | Time | Last change time for file1
"d" | boolean | True if file1 exists and is a directory
"e" | boolean | True if file1 exists
"f" | boolean | True if file1 exists and is a regular file
"g" | boolean | True if file1 has the setgid bit set
"G" | boolean | True if file1 exists and has a group
| | ownership equal to the caller's group
"k" | boolean | True if file1 exists and has the sticky bit set
"l" | boolean | True if file1 exists and is a symbolic link
"M" | Time | Last modification time for file1
"o" | boolean | True if file1 exists and is owned by
| | the caller's effective uid
"O" | boolean | True if file1 exists and is owned by
| | the caller's real uid
"p" | boolean | True if file1 exists and is a fifo
"r" | boolean | True if file1 is readable by the effective
| | uid/gid of the caller
"R" | boolean | True if file is readable by the real
| | uid/gid of the caller
"s" | int/nil | If file1 has nonzero size, return the size,
| | otherwise return nil
"S" | boolean | True if file1 exists and is a socket
"u" | boolean | True if file1 has the setuid bit set
"w" | boolean | True if file1 exists and is writable by
| | the effective uid/gid
"W" | boolean | True if file1 exists and is writable by
| | the real uid/gid
"x" | boolean | True if file1 exists and is executable by
| | the effective uid/gid
"X" | boolean | True if file1 exists and is executable by
| | the real uid/gid
"z" | boolean | True if file1 exists and has a zero length
Tests that take two files:
"-" | boolean | True if file1 and file2 are identical
"=" | boolean | True if the modification times of file1
| | and file2 are equal
"<" | boolean | True if the modification time of file1
| | is prior to that of file2
">" | boolean | True if the modification time of file1
| | is after that of file2
export #
ENV::[]=
(from ruby core)
ENV[name] = value -> value
ENV.store(name, value) -> value
ENV.store is an alias for ENV.[]=.
Creates, updates, or deletes the named environment variable, returning the value. Both name
and value
may be instances of String. See Valid Names and Values.
-
If the named environment variable does not exist:
-
If
value
isnil
, does nothing.ENV.clear ENV['foo'] = nil # => nil ENV.include?('foo') # => false ENV.store('bar', nil) # => nil ENV.include?('bar') # => false
-
If
value
is notnil
, creates the environment variable withname
andvalue
:# Create 'foo' using ENV.[]=. ENV['foo'] = '0' # => '0' ENV['foo'] # => '0' # Create 'bar' using ENV.store. ENV.store('bar', '1') # => '1' ENV['bar'] # => '1'
-
-
If the named environment variable exists:
-
If
value
is notnil
, updates the environment variable with valuevalue
:# Update 'foo' using ENV.[]=. ENV['foo'] = '2' # => '2' ENV['foo'] # => '2' # Update 'bar' using ENV.store. ENV.store('bar', '3') # => '3' ENV['bar'] # => '3'
-
If
value
isnil
, deletes the environment variable:# Delete 'foo' using ENV.[]=. ENV['foo'] = nil # => nil ENV.include?('foo') # => false # Delete 'bar' using ENV.store. ENV.store('bar', nil) # => nil ENV.include?('bar') # => false
-
Raises an exception if name
or value
is invalid. See Invalid Names and Values.
readonly #
Object#freeze
(from ruby core)
obj.freeze -> obj
Prevents further modifications to obj. A FrozenError will be raised if modification is attempted. There is no way to unfreeze a frozen object. See also Object#frozen?.
This method returns self.
a = [ "a", "b", "c" ]
a.freeze
a << "z"
produces:
prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
from prog.rb:3
Objects of the following classes are always frozen: Integer, Float, Symbol.
echo #
Kernel#print
(from ruby core)
print(*objects) -> nil
Equivalent to $stdout.print(*objects)
, this method is the straightforward way to write to $stdout
.
Writes the given objects to $stdout
; returns nil
. Appends the output record separator $OUTPUT_RECORD_SEPARATOR
$</tt>), if it is not <tt>nil
.
With argument objects
given, for each object:
-
Converts via its method
to_s
if not a string. -
Writes to
stdout
. -
If not the last object, writes the output field separator
$OUTPUT_FIELD_SEPARATOR
($,
if it is notnil
.
With default separators:
objects = [0, 0.0, Rational(0, 1), Complex(0, 0), :zero, 'zero']
$OUTPUT_RECORD_SEPARATOR
$OUTPUT_FIELD_SEPARATOR
print(*objects)
Output:
nil
nil
00.00/10+0izerozero
With specified separators:
$OUTPUT_RECORD_SEPARATOR = "\n"
$OUTPUT_FIELD_SEPARATOR = ','
print(*objects)
Output:
0,0.0,0/1,0+0i,zero,zero
With no argument given, writes the content of $_
(which is usually the most recent user input):
gets # Sets $_ to the most recent user input.
print # Prints $_.
Kernel#puts
(from ruby core)
puts(*objects) -> nil
Equivalent to
$stdout.puts(objects)
Kernel#p
(from ruby core)
p(object) -> obj
p(*objects) -> array of objects
p -> nil
For each object obj
, executes:
$stdout.write(obj.inspect, "\n")
With one object given, returns the object; with multiple objects given, returns an array containing the objects; with no object given, returns nil
.
Examples:
r = Range.new(0, 4)
p r # => 0..4
p [r, r, r] # => [0..4, 0..4, 0..4]
p # => nil
Output:
0..4
[0..4, 0..4, 0..4]
print
display an object (e.g: a string) as it is.puts
automatically adds a new line at the end.p
print object in raw form (mostly use for debug).
printf #
Kernel#printf
(from ruby core)
printf(format_string, *objects) -> nil
printf(io, format_string, *objects) -> nil
Equivalent to:
io.write(sprintf(format_string, *objects))
For details on format_string
, see Format Specifications.
With the single argument format_string
, formats objects
into the string, then writes the formatted string to $stdout:
printf('%4.4d %10s %2.2f', 24, 24, 24.0)
Output (on $stdout):
0024 24 24.00#
With arguments io
and format_string
, formats objects
into the string, then writes the formatted string to io
:
printf($stderr, '%4.4d %10s %2.2f', 24, 24, 24.0)
Output (on $stderr):
0024 24 24.00# => nil
With no arguments, does nothing.
read #
Kernel#gets
(from ruby core)
gets(sep=$/ [, getline_args]) -> string or nil
gets(limit [, getline_args]) -> string or nil
gets(sep, limit [, getline_args]) -> string or nil
Returns (and assigns to $_
) the next line from the list of files in ARGV
(or $*
), or from standard input if no files are present on the command line. Returns nil
at end of file. The optional argument specifies the record separator. The separator is included with the contents of each record. A separator of nil
reads the entire contents, and a zero-length separator reads the input one paragraph at a time, where paragraphs are divided by two consecutive newlines. If the first argument is an integer, or optional second argument is given, the returning string would not be longer than the given value in bytes. If multiple filenames are present in ARGV
, gets(nil)
will read the contents one file at a time.
ARGV << "testfile"
print while gets
produces:
This is line one
This is line two
This is line three
And so on...
The style of programming using $_
as an implicit parameter is gradually losing favor in the Ruby community.
IO#getpass
(from ruby core)
io.getpass(prompt=nil) -> string
Reads and returns a line without echo back. Prints prompt
unless it is nil
.
The newline character that terminates the read line is removed from the returned string, see String#chomp!.
You must require ‘io/console’ to use this method.
select #
Equivalent Ruby gem: tty-prompt
getopts #
OptionParser#getopts
(from ruby core)
getopts(*args)
Wrapper method for getopts.rb.
params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option")
# params["a"] = true # -a
# params["b"] = "1" # -b1
# params["foo"] = "1" # --foo
# params["bar"] = "x" # --bar x
# params["zot"] = "z" # --zot Z
eval #
Kernel#eval
(from ruby core)
eval(string [, binding [, filename [,lineno]]]) -> obj
Evaluates the Ruby expression(s) in string. If binding is given, which must be a Binding object, the evaluation is performed in its context. If the optional filename and lineno parameters are present, they will be used when reporting syntax errors.
def get_binding(str)
return binding
end
str = "hello"
eval "str + ' Fred'" #=> "hello Fred"
eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"
exec #
Kernel#exec
(from ruby core)
exec([env,] command... [,options])
Replaces the current process by running the given external command, which can take one of the following forms:
exec(commandline)
:
command line string which is passed to the standard shell
exec(cmdname, arg1, ...)
:
command name and one or more arguments (no shell)
exec([cmdname, argv0], arg1, ...)
:
command name, <tt>argv[0]</tt> and zero or more arguments (no shell)
In the first form, the string is taken as a command line that is subject to shell expansion before being executed.
The standard shell always means "/bin/sh"
on Unix-like systems, otherwise, ENV["RUBYSHELL"]
or ENV["COMSPEC"]
on Windows and similar. The command is passed as an argument to the "-c"
switch to the shell, except in the case of COMSPEC
.
If the string from the first form (exec("command")
) follows these simple rules:
-
no meta characters,
-
not starting with shell reserved word or special built-in,
Ruby invokes the command directly without shell.
You can force shell invocation by adding “;” to the string (because “;” is a meta character).
Note that this behavior is observable by pid obtained (return value of spawn() and IO#pid for IO.popen) is the pid of the invoked command, not shell.
In the second form (exec("command1", "arg1", ...)
), the first is taken as a command name and the rest are passed as parameters to command with no shell expansion.
In the third form (exec(["command", "argv0"], "arg1", ...)
), starting a two-element array at the beginning of the command, the first element is the command to be executed, and the second argument is used as the argv[0]
value, which may show up in process listings.
In order to execute the command, one of the exec(2)
system calls are used, so the running command may inherit some of the environment of the original program (including open file descriptors).
This behavior is modified by the given env
and options
parameters. See ::spawn for details.
If the command fails to execute (typically Errno::ENOENT when it was not found) a SystemCallError exception is raised.
This method modifies process attributes according to given options
before exec(2)
system call. See ::spawn for more details about the given options
.
The modified attributes may be retained when exec(2)
system call fails.
For example, hard resource limits are not restorable.
Consider to create a child process using ::spawn or Kernel#system if this is not acceptable.
exec "echo *" # echoes list of files in current directory
# never get here
exec "echo", "*" # echoes an asterisk
# never get here
exit #
Kernel#exit
(from ruby core)
exit(status=true)
Kernel::exit(status=true)
Process::exit(status=true)
Initiates the termination of the Ruby script by raising the SystemExit exception. This exception may be caught. The optional parameter is used to return a status code to the invoking environment. true
and FALSE
of status means success and failure respectively. The interpretation of other integer values are system dependent.
begin
exit
puts "never get here"
rescue SystemExit
puts "rescued a SystemExit exception"
end
puts "after begin block"
produces:
rescued a SystemExit exception
after begin block
Just prior to termination, Ruby executes any at_exit
functions (see Kernel::at_exit) and runs any object finalizers (see ObjectSpace::define_finalizer).
at_exit { puts "at_exit function" }
ObjectSpace.define_finalizer("string", proc { puts "in finalizer" })
exit
produces:
at_exit function
in finalizer
trap #
Kernel#trap
(from ruby core)
Signal.trap( signal, command ) -> obj
Signal.trap( signal ) {| | block } -> obj
Specifies the handling of signals. The first parameter is a signal name (a string such as “SIGALRM”, “SIGUSR1”, and so on) or a signal number. The characters “SIG” may be omitted from the signal name. The command or block specifies code to be run when the signal is raised. If the command is the string “IGNORE” or “SIG_IGN”, the signal will be ignored. If the command is “DEFAULT” or “SIG_DFL”, the Ruby’s default handler will be invoked. If the command is “EXIT”, the script will be terminated by the signal. If the command is “SYSTEM_DEFAULT”, the operating system’s default handler will be invoked. Otherwise, the given command or block will be run. The special signal name “EXIT” or signal number zero will be invoked just prior to program termination. trap returns the previous handler for the given signal.
Signal.trap(0, proc { puts "Terminating: #{$$}" })
Signal.trap("CLD") { puts "Child died" }
fork && Process.wait
produces:
Terminating: 27461
Child died
Terminating: 27460
cd #
Dir::chdir
(from ruby core)
Dir.chdir( [ string] ) -> 0
Dir.chdir( [ string] ) {| path | block } -> anObject
Changes the current working directory of the process to the given string. When called without an argument, changes the directory to the value of the environment variable HOME
, or LOGDIR
. SystemCallError (probably Errno::ENOENT) if the target directory does not exist.
If a block is given, it is passed the name of the new current directory, and the block is executed with that as the current directory. The original working directory is restored when the block exits. The return value of chdir
is the value of the block. chdir
blocks can be nested, but in a multi-threaded program an error will be raised if a thread attempts to open a chdir
block while another thread has one open or a call to chdir
without a block occurs inside a block passed to chdir
(even in the same thread).
Dir.chdir("/var/spool/mail")
puts Dir.pwd
Dir.chdir("/tmp") do
puts Dir.pwd
Dir.chdir("/usr") do
puts Dir.pwd
end
puts Dir.pwd
end
puts Dir.pwd
produces:
/var/spool/mail
/tmp
/usr
/tmp
/var/spool/mail
pwd #
Dir::pwd
(from ruby core)
Dir.getwd -> string
Dir.pwd -> string
Returns the path to the current working directory of this process as a string.
Dir.chdir("/tmp") #=> 0
Dir.getwd #=> "/tmp"
Dir.pwd #=> "/tmp"
Keywords
for #
Equivalent Ruby keyword: for
for
keyword, most of the time iterators should be used instead.
return #
Equivalent Ruby keyword: return
return
keyword where it's not required for flow of control.
Process Management
COMMAND & #
Thread::new
(from ruby core)
Thread.new { ... } -> thread
Thread.new(*args, &proc) -> thread
Thread.new(*args) { |args| ... } -> thread
Creates a new thread executing the given block.
Any args
given to ::new will be passed to the block:
arr = []
a, b, c = 1, 2, 3
Thread.new(a,b,c) { |d,e,f| arr << d << e << f }.join
arr #=> [1, 2, 3]
A ThreadError exception is raised if ::new is called without a block.
If you’re going to subclass Thread, be sure to call super in your initialize
method, otherwise a ThreadError will be raised.
Kernel#fork
(from ruby core)
Kernel.fork [{ block }] -> integer or nil
Process.fork [{ block }] -> integer or nil
Creates a subprocess. If a block is specified, that block is run in the subprocess, and the subprocess terminates with a status of zero. Otherwise, the fork
call returns twice, once in the parent, returning the process ID of the child, and once in the child, returning nil. The child process can exit using Kernel.exit! to avoid running any at_exit
functions. The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.
The thread calling fork is the only thread in the created child process. fork doesn’t copy other threads.
If fork is not usable, Process.respond_to?(:fork) returns false.
Note that fork(2) is not available on some platforms like Windows and NetBSD 4. Therefore you should use spawn() instead of fork().
jobs #
Thread::list
(from ruby core)
Thread.list -> array
Returns an array of Thread objects for all threads that are either runnable or stopped.
Thread.new { sleep(200) }
Thread.new { 1000000.times {|i| i*i } }
Thread.new { Thread.stop }
Thread.list.each {|t| p t}
This will produce:
#<Thread:0x401b3e84 sleep>
#<Thread:0x401b3f38 run>
#<Thread:0x401b3fb0 sleep>
#<Thread:0x401bdf4c run>
bg #
Thread#run
(from ruby core)
thr.run -> thr
Wakes up thr
, making it eligible for scheduling.
a = Thread.new { puts "a"; Thread.stop; puts "c" }
sleep 0.1 while a.status!='sleep'
puts "Got here"
a.run
a.join
This will produce:
a
Got here
c
See also the instance method #wakeup.
fg #
Thread#join
(from ruby core)
thr.join -> thr
thr.join(limit) -> thr
The calling thread will suspend execution and run this thr
.
Does not return until thr
exits or until the given limit
seconds have passed.
If the time limit expires, nil
will be returned, otherwise thr
is returned.
Any threads not joined will be killed when the main program exits.
If thr
had previously raised an exception and the ::abort_on_exception or $DEBUG flags are not set, (so the exception has not yet been processed), it will be processed at this time.
a = Thread.new { print "a"; sleep(10); print "b"; print "c" }
x = Thread.new { print "x"; Thread.pass; print "y"; print "z" }
x.join # Let thread x finish, thread a will be killed on exit.
#=> "axyz"
The following example illustrates the limit
parameter.
y = Thread.new { 4.times { sleep 0.1; puts 'tick... ' }}
puts "Waiting" until y.join(0.15)
This will produce:
tick...
Waiting
tick...
Waiting
tick...
tick...
suspend #
Thread::stop
(from ruby core)
Thread.stop -> nil
Stops execution of the current thread, putting it into a “sleep” state, and schedules execution of another thread.
a = Thread.new { print "a"; Thread.stop; print "c" }
sleep 0.1 while a.status!='sleep'
print "b"
a.run
a.join
#=> "abc"
kill #
Process::kill
(from ruby core)
Process.kill(signal, pid, *pids) -> integer
Sends the given signal to the specified process id(s) if pid is positive. If pid is zero, signal is sent to all processes whose group ID is equal to the group ID of the process. If pid is negative, results are dependent on the operating system. signal may be an integer signal number or a POSIX signal name (either with or without a SIG
prefix). If signal is negative (or starts with a minus sign), kills process groups instead of processes. Not all signals are available on all platforms. The keys and values of Signal.list are known signal names and numbers, respectively.
pid = fork do
Signal.trap("HUP") { puts "Ouch!"; exit }
# ... do some work ...
end
# ...
Process.kill("HUP", pid)
Process.wait
produces:
Ouch!
If signal is an integer but wrong for signal, Errno::EINVAL or RangeError will be raised. Otherwise unless signal is a String or a Symbol, and a known signal name, ArgumentError will be raised.
Also, Errno::ESRCH or RangeError for invalid pid, Errno::EPERM when failed because of no privilege, will be raised. In these cases, signals may have been sent to preceding processes.
wait #
Process::wait
(from ruby core)
Process.wait() -> integer
Process.wait(pid=-1, flags=0) -> integer
Process.waitpid(pid=-1, flags=0) -> integer
Waits for a child process to exit, returns its process id, and sets $?
to a Process::Status object containing information on that process. Which child it waits on depends on the value of pid:
> 0:
Waits for the child whose process ID equals <em>pid</em>.
0:
Waits for any child whose process group ID equals that of the calling
process.
-1:
Waits for any child process (the default if no <em>pid</em> is given).
< -1:
Waits for any child whose process group ID equals the absolute value
of <em>pid</em>.
The flags argument may be a logical or of the flag values Process::WNOHANG (do not block if no child available) or Process::WUNTRACED (return stopped children that haven’t been reported). Not all flags are available on all platforms, but a flag value of zero will work on all platforms.
Calling this method raises a SystemCallError if there are no child processes. Not available on all platforms.
include Process
fork { exit 99 } #=> 27429
wait #=> 27429
$?.exitstatus #=> 99
pid = fork { sleep 3 } #=> 27440
Time.now #=> 2008-03-08 19:56:16 +0900
waitpid(pid, Process::WNOHANG) #=> nil
Time.now #=> 2008-03-08 19:56:16 +0900
waitpid(pid, 0) #=> 27440
Time.now #=> 2008-03-08 19:56:19 +0900
time #
Benchmark::measure
(from ruby core)
measure(label = "") { || ... }
Returns the time used to execute the given block as a Benchmark::Tms object. Takes label
option.
require 'benchmark'
n = 1000000
time = Benchmark.measure do
n.times { a = "1" }
end
puts time
Generates:
0.220000 0.000000 0.220000 ( 0.227313)
disown #
Kernel#fork
(from ruby core)
Kernel.fork [{ block }] -> integer or nil
Process.fork [{ block }] -> integer or nil
Creates a subprocess. If a block is specified, that block is run in the subprocess, and the subprocess terminates with a status of zero. Otherwise, the fork
call returns twice, once in the parent, returning the process ID of the child, and once in the child, returning nil. The child process can exit using Kernel.exit! to avoid running any at_exit
functions. The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.
The thread calling fork is the only thread in the created child process. fork doesn’t copy other threads.
If fork is not usable, Process.respond_to?(:fork) returns false.
Note that fork(2) is not available on some platforms like Windows and NetBSD 4. Therefore you should use spawn() instead of fork().
Special Variables
$* $@ #
$*
or the ARGV
constant.
$# #
ARGV.size
$1 $2 $3 $4 $5 $6 $7 $8 $9 #
ARGV[0]
, ARGV[1]
, ARGV[2]
, ...
$0 #
__FILE__
$? #
$?
$$ $BASHPID #
$$
or Process.pid
.
$PPID #
Process::ppid
(from ruby core)
Process.ppid -> integer
Returns the process id of the parent of this process. Returns untrustworthy value on Win32/64. Not available on all platforms.
puts "I am #{Process.pid}"
Process.fork { puts "Dad is #{Process.ppid}" }
produces:
I am 27417
Dad is 27417
$BASH_VERSINFO $BASH_VERSION #
RUBY_VERSION
$HOSTNAME #
Socket::gethostname
(from ruby core)
Socket.gethostname => hostname
Returns the hostname.
p Socket.gethostname #=> "hal"
Note that it is not guaranteed to be able to convert to IP address using gethostbyname, getaddrinfo, etc. If you need local IP address, use Socket.ip_address_list.
$EUID #
Process::uid
(from ruby core)
Process.uid -> integer
Process::UID.rid -> integer
Process::Sys.getuid -> integer
Returns the (real) user ID of this process.
Process.uid #=> 501
Process.uid == 0
.
$HOSTTYPE #
Gem::Platform.local.cpu
$LINES #
IO.console.winsize[0]
$COLUMNS #
IO.console.winsize[1]
$PWD #
Dir::pwd
(from ruby core)
Dir.getwd -> string
Dir.pwd -> string
Returns the path to the current working directory of this process as a string.
Dir.chdir("/tmp") #=> 0
Dir.getwd #=> "/tmp"
Dir.pwd #=> "/tmp"
$HOME #
Dir::home
(from ruby core)
Dir.home() -> "/home/me"
Dir.home("root") -> "/root"
Returns the home directory of the current user or the named user if given.
$RANDOM $SRANDOM #
Kernel#rand
(from ruby core)
rand(max=0) -> number
If called without an argument, or if max.to_i.abs == 0
, rand returns a pseudo-random floating point number between 0.0 and 1.0, including 0.0 and excluding 1.0.
rand #=> 0.2725926052826416
When max.abs
is greater than or equal to 1, rand
returns a pseudo-random integer greater than or equal to 0 and less than max.to_i.abs
.
rand(100) #=> 12
When max
is a Range, rand
returns a random number where range.member?(number) == true
.
Negative or floating point values for max
are allowed, but may give surprising results.
rand(-100) # => 87
rand(-0.5) # => 0.8130921818028143
rand(1.9) # equivalent to rand(1), which is always 0
Kernel.srand may be used to ensure that sequences of random numbers are reproducible between different runs of a program.
See also Random.rand.
$SECONDS #
Time < Object
Includes:
Comparable (from ruby core)
(from ruby core)
A Time object represents a date and time:
Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600
Although its value can be expressed as a single numeric (see Epoch Seconds below), it can be convenient to deal with the value by parts:
t = Time.new(-2000, 1, 1, 0, 0, 0.0)
# => -2000-01-01 00:00:00 -0600
t.year # => -2000
t.month # => 1
t.mday # => 1
t.hour # => 0
t.min # => 0
t.sec # => 0
t.subsec # => 0
t = Time.new(2000, 12, 31, 23, 59, 59.5)
# => 2000-12-31 23:59:59.5 -0600
t.year # => 2000
t.month # => 12
t.mday # => 31
t.hour # => 23
t.min # => 59
t.sec # => 59
t.subsec # => (1/2)
Epoch Seconds
Epoch seconds is the exact number of seconds (including fractional subseconds) since the Unix Epoch, January 1, 1970.
You can retrieve that value exactly using method Time.to_r:
Time.at(0).to_r # => (0/1)
Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)
Other retrieval methods such as Time#to_i and Time#to_f may return a value that rounds or truncates subseconds.
Time Resolution
A Time object derived from the system clock (for example, by method Time.now) has the resolution supported by the system.
Examples
All of these examples were done using the EST timezone which is GMT-5.
Creating a New Time Instance
You can create a new instance of Time with Time.new. This will use the current system time. Time.now is an alias for this. You can also pass parts of the time to Time.new such as year, month, minute, etc. When you want to construct a time this way you must pass at least a year. If you pass the year with nothing else time will default to January 1 of that year at 00:00:00 with the current system timezone. Here are some examples:
Time.new(2002) #=> 2002-01-01 00:00:00 -0500
Time.new(2002, 10) #=> 2002-10-01 00:00:00 -0500
Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500
You can pass a UTC offset:
Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200
Or a timezone object:
zone = timezone("Europe/Athens") # Eastern European Time, UTC+2
Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200
You can also use Time.local and Time.utc to infer local and UTC timezones instead of using the current system setting.
You can also create a new time using Time.at which takes the number of seconds (with subsecond) since the Unix Epoch.
Time.at(628232400) #=> 1989-11-28 00:00:00 -0500
Working with an Instance of Time
Once you have an instance of Time there is a multitude of things you can do with it. Below are some examples. For all of the following examples, we will work on the assumption that you have done the following:
t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")
Was that a monday?
t.monday? #=> false
What year was that again?
t.year #=> 1993
Was it daylight savings at the time?
t.dst? #=> false
What’s the day a year later?
t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900
How many seconds was that since the Unix Epoch?
t.to_i #=> 730522800
You can also do standard functions like compare two times.
t1 = Time.new(2010)
t2 = Time.new(2011)
t1 == t2 #=> false
t1 == t1 #=> true
t1 < t2 #=> true
t1 > t2 #=> false
Time.new(2010,10,31).between?(t1, t2) #=> true
What’s Here
First, what’s elsewhere. Class Time:
-
Inherits from class Object.
-
Includes module Comparable.
Here, class Time provides methods that are useful for:
Methods for Creating
-
::new: Returns a new time from specified arguments (year, month, etc.), including an optional timezone value.
-
::local (aliased as ::mktime): Same as ::new, except the timezone is the local timezone.
-
::utc (aliased as ::gm): Same as ::new, except the timezone is UTC.
-
::at: Returns a new time based on seconds since epoch.
-
::now: Returns a new time based on the current system time.
-
#+ (plus): Returns a new time increased by the given number of seconds.
-
#- (minus): Returns a new time decreased by the given number of seconds.
Methods for Fetching
-
#year: Returns the year of the time.
-
#month (aliased as #mon): Returns the month of the time.
-
#mday (aliased as #day): Returns the day of the month.
-
#hour: Returns the hours value for the time.
-
#min: Returns the minutes value for the time.
-
#sec: Returns the seconds value for the time.
-
#usec (aliased as #tv_usec): Returns the number of microseconds in the subseconds value of the time.
-
#nsec (aliased as #tv_nsec: Returns the number of nanoseconds in the subsecond part of the time.
-
#subsec: Returns the subseconds value for the time.
-
#wday: Returns the integer weekday value of the time (0 == Sunday).
-
#yday: Returns the integer yearday value of the time (1 == January 1).
-
#hash: Returns the integer hash value for the time.
-
#utc_offset (aliased as #gmt_offset and #gmtoff): Returns the offset in seconds between time and UTC.
-
#to_f: Returns the float number of seconds since epoch for the time.
-
#to_i (aliased as #tv_sec): Returns the integer number of seconds since epoch for the time.
-
#to_r: Returns the Rational number of seconds since epoch for the time.
-
#zone: Returns a string representation of the timezone of the time.
Methods for Querying
-
#utc? (aliased as #gmt?): Returns whether the time is UTC.
-
#dst? (aliased as #isdst): Returns whether the time is DST (daylight saving time).
-
#sunday?: Returns whether the time is a Sunday.
-
#monday?: Returns whether the time is a Monday.
-
#tuesday?: Returns whether the time is a Tuesday.
-
#wednesday?: Returns whether the time is a Wednesday.
-
#thursday?: Returns whether the time is a Thursday.
-
#friday?: Returns whether time is a Friday.
-
#saturday?: Returns whether the time is a Saturday.
Methods for Comparing
-
#<=>: Compares
self
to another time. -
#eql?: Returns whether the time is equal to another time.
Methods for Converting
-
#asctime (aliased as #ctime): Returns the time as a string.
-
#inspect: Returns the time in detail as a string.
-
#strftime: Returns the time as a string, according to a given format.
-
#to_a: Returns a 10-element array of values from the time.
-
#to_s: Returns a string representation of the time.
-
#getutc (aliased as #getgm): Returns a new time converted to UTC.
-
#getlocal: Returns a new time converted to local time.
-
#utc (aliased as #gmtime): Converts time to UTC in place.
-
#localtime: Converts time to local time in place.
-
#deconstruct_keys: Returns a hash of time components used in pattern-matching.
Methods for Rounding
-
#round:Returns a new time with subseconds rounded.
-
#ceil: Returns a new time with subseconds raised to a ceiling.
-
#floor: Returns a new time with subseconds lowered to a floor.
For the forms of argument zone
, see Timezone Specifiers.
Class methods:
at
gm
httpdate
iso8601
json_create
local
mktime
new
now
parse
rfc2822
rfc822
strptime
utc
xmlschema
zone_offset
Instance methods:
+
-
<=>
as_json
asctime
ceil
ctime
day
deconstruct_keys
dst?
eql?
floor
friday?
getgm
getlocal
getutc
gmt?
gmt_offset
gmtime
gmtoff
hash
hour
httpdate
inspect
isdst
iso8601
localtime
mday
min
mon
monday?
month
nsec
rfc2822
rfc822
round
saturday?
sec
strftime
subsec
sunday?
thursday?
to_a
to_date
to_datetime
to_f
to_i
to_json
to_r
to_s
to_time
tuesday?
tv_nsec
tv_sec
tv_usec
usec
utc
utc?
utc_offset
wday
wednesday?
xmlschema
yday
year
zone
$EPOCHREALTIME #
Time#to_f
(from ruby core)
to_f -> float
Returns the value of self
as a Float number Epoch seconds; subseconds are included.
The stored value of self
is a Rational, which means that the returned value may be approximate:
Time.utc(1970, 1, 1, 0, 0, 0).to_f # => 0.0
Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_f # => 0.999999
Time.utc(1950, 1, 1, 0, 0, 0).to_f # => -631152000.0
Time.utc(1990, 1, 1, 0, 0, 0).to_f # => 631152000.0
Related: Time#to_i, Time#to_r.
$EPOCHSECONDS #
Time#to_i
(from ruby core)
to_i -> integer
Returns the value of self
as integer Epoch seconds; subseconds are truncated (not rounded):
Time.utc(1970, 1, 1, 0, 0, 0).to_i # => 0
Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_i # => 0
Time.utc(1950, 1, 1, 0, 0, 0).to_i # => -631152000
Time.utc(1990, 1, 1, 0, 0, 0).to_i # => 631152000
Time#tv_sec is an alias for Time#to_i.
Related: Time#to_f Time#to_r.
$TMPDIR #
Dir::tmpdir
(from ruby core)
tmpdir()
Returns the operating system’s temporary file path.
System's Executables
Basic Commands
bc dc expr #
Math
module.
env printenv locale #
ENV < Object
(from ruby core)
ENV is a hash-like accessor for environment variables.
Interaction with the Operating System
The ENV object interacts with the operating system’s environment variables:
-
When you get the value for a name in ENV, the value is retrieved from among the current environment variables.
-
When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.
-
When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.
Names and Values
Generally, a name or value is a String.
Valid Names and Values
Each name or value must be one of the following:
-
A String.
-
An object that responds to #to_str by returning a String, in which case that String will be used as the name or value.
Invalid Names and Values
A new name:
-
May not be the empty string:
ENV[''] = '0' # Raises Errno::EINVAL (Invalid argument - ruby_setenv())
-
May not contain character
"="
:ENV['='] = '0' # Raises Errno::EINVAL (Invalid argument - ruby_setenv(=))
A new name or value:
-
May not be a non-String that does not respond to #to_str:
ENV['foo'] = Object.new # Raises TypeError (no implicit conversion of Object into String) ENV[Object.new] = '0' # Raises TypeError (no implicit conversion of Object into String)
-
May not contain the NUL character
"\0"
:ENV['foo'] = "\0" # Raises ArgumentError (bad environment variable value: contains null byte) ENV["\0"] == '0' # Raises ArgumentError (bad environment variable name: contains null byte)
-
May not have an ASCII-incompatible encoding such as UTF-16LE or ISO-2022-JP:
ENV['foo'] = '0'.force_encoding(Encoding::ISO_2022_JP) # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP) ENV["foo".force_encoding(Encoding::ISO_2022_JP)] = '0' # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
About Ordering
ENV enumerates its name/value pairs in the order found in the operating system’s environment variables. Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.
This will be seen in:
-
A Hash returned by an ENV method.
-
An Enumerator returned by an ENV method.
-
An Array returned by ENV.keys, ENV.values, or ENV.to_a.
-
The String returned by ENV.inspect.
-
The Array returned by ENV.shift.
-
The name returned by ENV.key.
About the Examples
Some methods in ENV return ENV itself. Typically, there are many environment variables. It’s not useful to display a large ENV in the examples here, so most example snippets begin by resetting the contents of ENV:
-
ENV.replace replaces ENV with a new collection of entries.
-
ENV.clear empties ENV.
What’s Here
First, what’s elsewhere. Class ENV:
-
Inherits from class Object.
-
Extends module Enumerable,
Here, class ENV provides methods that are useful for:
Methods for Querying
-
::[]: Returns the value for the given environment variable name if it exists:
-
::empty?: Returns whether ENV is empty.
-
::has_value?, ::value?: Returns whether the given value is in ENV.
-
::include?, ::has_key?, ::key?, ::member?: Returns whether the given name is in ENV.
-
::key: Returns the name of the first entry with the given value.
-
::size, ::length: Returns the number of entries.
-
::value?: Returns whether any entry has the given value.
Methods for Assigning
-
::[]=, ::store: Creates, updates, or deletes the named environment variable.
-
::clear: Removes every environment variable; returns ENV:
-
::update, ::merge!: Adds to ENV each key/value pair in the given hash.
-
::replace: Replaces the entire content of the ENV with the name/value pairs in the given hash.
Methods for Deleting
-
::delete: Deletes the named environment variable name if it exists.
-
::delete_if: Deletes entries selected by the block.
-
::keep_if: Deletes entries not selected by the block.
-
::reject!: Similar to #delete_if, but returns
nil
if no change was made. -
::select!, ::filter!: Deletes entries selected by the block.
-
::shift: Removes and returns the first entry.
Methods for Iterating
-
::each, ::each_pair: Calls the block with each name/value pair.
-
::each_key: Calls the block with each name.
-
::each_value: Calls the block with each value.
Methods for Converting
-
::assoc: Returns a 2-element array containing the name and value of the named environment variable if it exists:
-
::clone: Returns ENV (and issues a warning).
-
::except: Returns a hash of all name/value pairs except those given.
-
::fetch: Returns the value for the given name.
-
::inspect: Returns the contents of ENV as a string.
-
::invert: Returns a hash whose keys are the ENV values, and whose values are the corresponding ENV names.
-
::keys: Returns an array of all names.
-
::rassoc: Returns the name and value of the first found entry that has the given value.
-
::reject: Returns a hash of those entries not rejected by the block.
-
::select, ::filter: Returns a hash of name/value pairs selected by the block.
-
::slice: Returns a hash of the given names and their corresponding values.
-
::to_a: Returns the entries as an array of 2-element Arrays.
-
::to_h: Returns a hash of entries selected by the block.
-
::to_hash: Returns a hash of all entries.
-
::to_s: Returns the string
'ENV'
. -
::values: Returns all values as an array.
-
::values_at: Returns an array of the values for the given name.
More Methods
-
::dup: Raises an exception.
-
::freeze: Raises an exception.
-
::rehash: Returns
nil
, without modifying ENV.
Class methods:
[]
[]=
assoc
clear
clone
delete
delete_if
dup
each
each_key
each_pair
each_value
empty?
except
fetch
filter
filter!
freeze
has_key?
has_value?
include?
inspect
invert
keep_if
key
key?
keys
length
member?
merge!
rassoc
rehash
reject
reject!
replace
select
select!
shift
size
slice
store
to_a
to_h
to_hash
to_s
update
value?
values
values_at
xargs #
Kernel#then
(from ruby core)
obj.then {|x| block } -> an_object
Yields self to the block and returns the result of the block.
3.next.then {|x| x**x }.to_s #=> "256"
Good usage for then
is value piping in method chains:
require 'open-uri'
require 'json'
construct_url(arguments).
then {|url| URI(url).read }.
then {|response| JSON.parse(response) }
When called without block, the method returns Enumerator
, which can be used, for example, for conditional circuit-breaking:
# meets condition, no-op
1.then.detect(&:odd?) # => 1
# does not meet condition, drop value
2.then.detect(&:odd?) # => nil
an_object.then { do_somethings_with _1 }
watch #
Kernel#loop
(from ruby core)
loop { block }
loop -> an_enumerator
Repeatedly executes the block.
If no block is given, an enumerator is returned instead.
loop do
print "Input: "
line = gets
break if !line or line =~ /^q/i
# ...
end
StopIteration raised in the block breaks the loop. In this case, loop returns the “result” value stored in the exception.
enum = Enumerator.new { |y|
y << "one"
y << "two"
:ok
}
result = loop {
puts enum.next
} #=> :ok
pee #
Kernel#tap
(from ruby core)
obj.tap {|x| block } -> obj
Yields self to the block, and then returns self. The primary purpose of this method is to “tap into” a method chain, in order to perform operations on intermediate results within the chain.
(1..10) .tap {|x| puts "original: #{x}" }
.to_a .tap {|x| puts "array: #{x}" }
.select {|x| x.even? } .tap {|x| puts "evens: #{x}" }
.map {|x| x*x } .tap {|x| puts "squares: #{x}" }
getopt #
OptionParser < Object
(from ruby core)
OptionParser
New to OptionParser?
See the Tutorial.
Introduction
OptionParser is a class for command-line option analysis. It is much more advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented solution.
Features
-
The argument specification and the code to handle it are written in the same place.
-
It can output an option summary; you don’t need to maintain this string separately.
-
Optional and mandatory arguments are specified very gracefully.
-
Arguments can be automatically converted to a specified class.
-
Arguments can be restricted to a certain set.
All of these features are demonstrated in the examples below. See #make_switch for full documentation.
Minimal example
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.banner = "Usage: example.rb [options]"
parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
end.parse!
p options
p ARGV
Generating Help
OptionParser can be used to automatically generate help for the commands you write:
require 'optparse'
Options = Struct.new(:name)
class Parser
def self.parse(options)
args = Options.new("world")
opt_parser = OptionParser.new do |parser|
parser.banner = "Usage: example.rb [options]"
parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
args.name = n
end
parser.on("-h", "--help", "Prints this help") do
puts parser
exit
end
end
opt_parser.parse!(options)
return args
end
end
options = Parser.parse %w[--help]
#=>
# Usage: example.rb [options]
# -n, --name=NAME Name to say hello to
# -h, --help Prints this help
Required Arguments
For options that require an argument, option specification strings may include an option name in all caps. If an option is used without the required argument, an exception will be raised.
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.on("-r", "--require LIBRARY",
"Require the LIBRARY before executing your script") do |lib|
puts "You required #{lib}!"
end
end.parse!
Used:
$ ruby optparse-test.rb -r
optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument)
$ ruby optparse-test.rb -r my-library
You required my-library!
Type Coercion
OptionParser supports the ability to coerce command line arguments into objects for us.
OptionParser comes with a few ready-to-use kinds of type coercion. They are:
-
Date – Anything accepted by
Date.parse
-
DateTime – Anything accepted by
DateTime.parse
-
Time – Anything accepted by
Time.httpdate
orTime.parse
-
URI – Anything accepted by
URI.parse
-
Shellwords – Anything accepted by
Shellwords.shellwords
-
String – Any non-empty string
-
Integer – Any integer. Will convert octal. (e.g. 124, -3, 040)
-
Float – Any float. (e.g. 10, 3.14, -100E+13)
-
Numeric – Any integer, float, or rational (1, 3.4, 1/3)
-
DecimalInteger – Like
Integer
, but no octal format. -
OctalInteger – Like
Integer
, but no decimal format. -
DecimalNumeric – Decimal integer or float.
-
TrueClass – Accepts ‘+, yes, true, -, no, false’ and defaults as
true
-
FalseClass – Same as
TrueClass
, but defaults tofalse
-
Array – Strings separated by ‘,’ (e.g. 1,2,3)
-
Regexp – Regular expressions. Also includes options.
We can also add our own coercions, which we will cover below.
Using Built-in Conversions
As an example, the built-in Time
conversion is used. The other built-in conversions behave in the same way. OptionParser will attempt to parse the argument as a Time
. If it succeeds, that time will be passed to the handler block. Otherwise, an exception will be raised.
require 'optparse'
require 'optparse/time'
OptionParser.new do |parser|
parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
p time
end
end.parse!
Used:
$ ruby optparse-test.rb -t nonsense
... invalid argument: -t nonsense (OptionParser::InvalidArgument)
$ ruby optparse-test.rb -t 10-11-12
2010-11-12 00:00:00 -0500
$ ruby optparse-test.rb -t 9:30
2014-08-13 09:30:00 -0400
Creating Custom Conversions
The accept
method on OptionParser may be used to create converters. It specifies which conversion block to call whenever a class is specified. The example below uses it to fetch a User
object before the on
handler receives it.
require 'optparse'
User = Struct.new(:id, :name)
def find_user id
not_found = ->{ raise "No User Found for id #{id}" }
[ User.new(1, "Sam"),
User.new(2, "Gandalf") ].find(not_found) do |u|
u.id == id
end
end
op = OptionParser.new
op.accept(User) do |user_id|
find_user user_id.to_i
end
op.on("--user ID", User) do |user|
puts user
end
op.parse!
Used:
$ ruby optparse-test.rb --user 1
#<struct User id=1, name="Sam">
$ ruby optparse-test.rb --user 2
#<struct User id=2, name="Gandalf">
$ ruby optparse-test.rb --user 3
optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
Store options to a Hash
The into
option of order
, parse
and so on methods stores command line options into a Hash.
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.on('-a')
parser.on('-b NUM', Integer)
parser.on('-v', '--verbose')
end.parse!(into: options)
p options
Used:
$ ruby optparse-test.rb -a
{:a=>true}
$ ruby optparse-test.rb -a -v
{:a=>true, :verbose=>true}
$ ruby optparse-test.rb -a -b 100
{:a=>true, :b=>100}
Complete example
The following example is a complete Ruby program. You can run it and see the effect of specifying various options. This is probably the best way to learn the features of optparse
.
require 'optparse'
require 'optparse/time'
require 'ostruct'
require 'pp'
class OptparseExample
Version = '1.0.0'
CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
class ScriptOptions
attr_accessor :library, :inplace, :encoding, :transfer_type,
:verbose, :extension, :delay, :time, :record_separator,
:list
def initialize
self.library = []
self.inplace = false
self.encoding = "utf8"
self.transfer_type = :auto
self.verbose = false
end
def define_options(parser)
parser.banner = "Usage: example.rb [options]"
parser.separator ""
parser.separator "Specific options:"
# add additional options
perform_inplace_option(parser)
delay_execution_option(parser)
execute_at_time_option(parser)
specify_record_separator_option(parser)
list_example_option(parser)
specify_encoding_option(parser)
optional_option_argument_with_keyword_completion_option(parser)
boolean_verbose_option(parser)
parser.separator ""
parser.separator "Common options:"
# No argument, shows at tail. This will print an options summary.
# Try it and see!
parser.on_tail("-h", "--help", "Show this message") do
puts parser
exit
end
# Another typical switch to print the version.
parser.on_tail("--version", "Show version") do
puts Version
exit
end
end
def perform_inplace_option(parser)
# Specifies an optional option argument
parser.on("-i", "--inplace [EXTENSION]",
"Edit ARGV files in place",
"(make backup if EXTENSION supplied)") do |ext|
self.inplace = true
self.extension = ext || ''
self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
end
end
def delay_execution_option(parser)
# Cast 'delay' argument to a Float.
parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
self.delay = n
end
end
def execute_at_time_option(parser)
# Cast 'time' argument to a Time object.
parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
self.time = time
end
end
def specify_record_separator_option(parser)
# Cast to octal integer.
parser.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
"Specify record separator (default \\0)") do |rs|
self.record_separator = rs
end
end
def list_example_option(parser)
# List of arguments.
parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
self.list = list
end
end
def specify_encoding_option(parser)
# Keyword completion. We are specifying a specific set of arguments (CODES
# and CODE_ALIASES - notice the latter is a Hash), and the user may provide
# the shortest unambiguous text.
code_list = (CODE_ALIASES.keys + CODES).join(', ')
parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
"(#{code_list})") do |encoding|
self.encoding = encoding
end
end
def optional_option_argument_with_keyword_completion_option(parser)
# Optional '--type' option argument with keyword completion.
parser.on("--type [TYPE]", [:text, :binary, :auto],
"Select transfer type (text, binary, auto)") do |t|
self.transfer_type = t
end
end
def boolean_verbose_option(parser)
# Boolean switch.
parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
self.verbose = v
end
end
end
#
# Return a structure describing the options.
#
def parse(args)
# The options specified on the command line will be collected in
# *options*.
@options = ScriptOptions.new
@args = OptionParser.new do |parser|
@options.define_options(parser)
parser.parse!(args)
end
@options
end
attr_reader :parser, :options
end # class OptparseExample
example = OptparseExample.new
options = example.parse(ARGV)
pp options # example.options
pp ARGV
Shell Completion
For modern shells (e.g. bash, zsh, etc.), you can use shell completion for command line options.
Further documentation
The above examples, along with the accompanying Tutorial, should be enough to learn how to use this class. If you have any questions, file a ticket at bugs.ruby-lang.org.
Constants:
DecimalInteger:
Decimal integer format, to be converted to Integer.
DecimalNumeric:
Decimal integer/float number format, to be converted to Integer for
integer format, Float for float format.
OctalInteger:
Ruby/C like octal/hexadecimal/binary integer format, to be converted
to Integer.
Version:
[not documented]
Class methods:
accept
each_const
getopts
inc
new
reject
search_const
show_version
terminate
top
with
Instance methods:
abort
accept
additional_message
banner
base
candidate
def_head_option
def_option
def_tail_option
default_argv
define
define_by_keywords
define_head
define_tail
environment
getopts
help
inc
load
make_switch
new
on
on_head
on_tail
order
order!
parse
parse!
permute
permute!
program_name
raise_unknown
reject
release
remove
require_exact
separator
set_banner
set_program_name
set_summary_indent
set_summary_width
summarize
summary_indent
summary_width
terminate
to_a
to_s
top
ver
version
warn
Attributes:
attr_accessor default_argv
attr_accessor raise_unknown
attr_accessor require_exact
attr_accessor set_summary_indent
attr_accessor set_summary_width
attr_accessor summary_indent
attr_accessor summary_width
attr_writer banner
attr_writer program_name
attr_writer release
attr_writer set_banner
attr_writer set_program_name
attr_writer version
seq #
Range#to_a
(from ruby core)
to_a -> array
Returns an array containing the elements in self
, if a finite collection; raises an exception otherwise.
(1..4).to_a # => [1, 2, 3, 4]
(1...4).to_a # => [1, 2, 3]
('a'..'d').to_a # => ["a", "b", "c", "d"]
Range#entries is an alias for Range#to_a.
[*1..5]
and it will return [1, 2, 3, 4, 5]
.
date #
Time < Object
Includes:
Comparable (from ruby core)
(from ruby core)
A Time object represents a date and time:
Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600
Although its value can be expressed as a single numeric (see Epoch Seconds below), it can be convenient to deal with the value by parts:
t = Time.new(-2000, 1, 1, 0, 0, 0.0)
# => -2000-01-01 00:00:00 -0600
t.year # => -2000
t.month # => 1
t.mday # => 1
t.hour # => 0
t.min # => 0
t.sec # => 0
t.subsec # => 0
t = Time.new(2000, 12, 31, 23, 59, 59.5)
# => 2000-12-31 23:59:59.5 -0600
t.year # => 2000
t.month # => 12
t.mday # => 31
t.hour # => 23
t.min # => 59
t.sec # => 59
t.subsec # => (1/2)
Epoch Seconds
Epoch seconds is the exact number of seconds (including fractional subseconds) since the Unix Epoch, January 1, 1970.
You can retrieve that value exactly using method Time.to_r:
Time.at(0).to_r # => (0/1)
Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)
Other retrieval methods such as Time#to_i and Time#to_f may return a value that rounds or truncates subseconds.
Time Resolution
A Time object derived from the system clock (for example, by method Time.now) has the resolution supported by the system.
Examples
All of these examples were done using the EST timezone which is GMT-5.
Creating a New Time Instance
You can create a new instance of Time with Time.new. This will use the current system time. Time.now is an alias for this. You can also pass parts of the time to Time.new such as year, month, minute, etc. When you want to construct a time this way you must pass at least a year. If you pass the year with nothing else time will default to January 1 of that year at 00:00:00 with the current system timezone. Here are some examples:
Time.new(2002) #=> 2002-01-01 00:00:00 -0500
Time.new(2002, 10) #=> 2002-10-01 00:00:00 -0500
Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500
You can pass a UTC offset:
Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200
Or a timezone object:
zone = timezone("Europe/Athens") # Eastern European Time, UTC+2
Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200
You can also use Time.local and Time.utc to infer local and UTC timezones instead of using the current system setting.
You can also create a new time using Time.at which takes the number of seconds (with subsecond) since the Unix Epoch.
Time.at(628232400) #=> 1989-11-28 00:00:00 -0500
Working with an Instance of Time
Once you have an instance of Time there is a multitude of things you can do with it. Below are some examples. For all of the following examples, we will work on the assumption that you have done the following:
t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")
Was that a monday?
t.monday? #=> false
What year was that again?
t.year #=> 1993
Was it daylight savings at the time?
t.dst? #=> false
What’s the day a year later?
t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900
How many seconds was that since the Unix Epoch?
t.to_i #=> 730522800
You can also do standard functions like compare two times.
t1 = Time.new(2010)
t2 = Time.new(2011)
t1 == t2 #=> false
t1 == t1 #=> true
t1 < t2 #=> true
t1 > t2 #=> false
Time.new(2010,10,31).between?(t1, t2) #=> true
What’s Here
First, what’s elsewhere. Class Time:
-
Inherits from class Object.
-
Includes module Comparable.
Here, class Time provides methods that are useful for:
Methods for Creating
-
::new: Returns a new time from specified arguments (year, month, etc.), including an optional timezone value.
-
::local (aliased as ::mktime): Same as ::new, except the timezone is the local timezone.
-
::utc (aliased as ::gm): Same as ::new, except the timezone is UTC.
-
::at: Returns a new time based on seconds since epoch.
-
::now: Returns a new time based on the current system time.
-
#+ (plus): Returns a new time increased by the given number of seconds.
-
#- (minus): Returns a new time decreased by the given number of seconds.
Methods for Fetching
-
#year: Returns the year of the time.
-
#month (aliased as #mon): Returns the month of the time.
-
#mday (aliased as #day): Returns the day of the month.
-
#hour: Returns the hours value for the time.
-
#min: Returns the minutes value for the time.
-
#sec: Returns the seconds value for the time.
-
#usec (aliased as #tv_usec): Returns the number of microseconds in the subseconds value of the time.
-
#nsec (aliased as #tv_nsec: Returns the number of nanoseconds in the subsecond part of the time.
-
#subsec: Returns the subseconds value for the time.
-
#wday: Returns the integer weekday value of the time (0 == Sunday).
-
#yday: Returns the integer yearday value of the time (1 == January 1).
-
#hash: Returns the integer hash value for the time.
-
#utc_offset (aliased as #gmt_offset and #gmtoff): Returns the offset in seconds between time and UTC.
-
#to_f: Returns the float number of seconds since epoch for the time.
-
#to_i (aliased as #tv_sec): Returns the integer number of seconds since epoch for the time.
-
#to_r: Returns the Rational number of seconds since epoch for the time.
-
#zone: Returns a string representation of the timezone of the time.
Methods for Querying
-
#utc? (aliased as #gmt?): Returns whether the time is UTC.
-
#dst? (aliased as #isdst): Returns whether the time is DST (daylight saving time).
-
#sunday?: Returns whether the time is a Sunday.
-
#monday?: Returns whether the time is a Monday.
-
#tuesday?: Returns whether the time is a Tuesday.
-
#wednesday?: Returns whether the time is a Wednesday.
-
#thursday?: Returns whether the time is a Thursday.
-
#friday?: Returns whether time is a Friday.
-
#saturday?: Returns whether the time is a Saturday.
Methods for Comparing
-
#<=>: Compares
self
to another time. -
#eql?: Returns whether the time is equal to another time.
Methods for Converting
-
#asctime (aliased as #ctime): Returns the time as a string.
-
#inspect: Returns the time in detail as a string.
-
#strftime: Returns the time as a string, according to a given format.
-
#to_a: Returns a 10-element array of values from the time.
-
#to_s: Returns a string representation of the time.
-
#getutc (aliased as #getgm): Returns a new time converted to UTC.
-
#getlocal: Returns a new time converted to local time.
-
#utc (aliased as #gmtime): Converts time to UTC in place.
-
#localtime: Converts time to local time in place.
-
#deconstruct_keys: Returns a hash of time components used in pattern-matching.
Methods for Rounding
-
#round:Returns a new time with subseconds rounded.
-
#ceil: Returns a new time with subseconds raised to a ceiling.
-
#floor: Returns a new time with subseconds lowered to a floor.
For the forms of argument zone
, see Timezone Specifiers.
Class methods:
at
gm
httpdate
iso8601
json_create
local
mktime
new
now
parse
rfc2822
rfc822
strptime
utc
xmlschema
zone_offset
Instance methods:
+
-
<=>
as_json
asctime
ceil
ctime
day
deconstruct_keys
dst?
eql?
floor
friday?
getgm
getlocal
getutc
gmt?
gmt_offset
gmtime
gmtoff
hash
hour
httpdate
inspect
isdst
iso8601
localtime
mday
min
mon
monday?
month
nsec
rfc2822
rfc822
round
saturday?
sec
strftime
subsec
sunday?
thursday?
to_a
to_date
to_datetime
to_f
to_i
to_json
to_r
to_s
to_time
tuesday?
tv_nsec
tv_sec
tv_usec
usec
utc
utc?
utc_offset
wday
wednesday?
xmlschema
yday
year
zone
sleep usleep #
Kernel#sleep
(from ruby core)
sleep([duration]) -> integer
Suspends the current thread for duration seconds (which may be any number, including a Float
with fractional seconds). Returns the actual number of seconds slept (rounded), which may be less than that asked for if another thread calls Thread#run. Called without an argument, sleep() will sleep forever.
Time.new #=> 2008-03-08 19:56:19 +0900
sleep 1.2 #=> 1
Time.new #=> 2008-03-08 19:56:20 +0900
sleep 1.9 #=> 2
Time.new #=> 2008-03-08 19:56:22 +0900
timeout #
Timeout
(from ruby core)
Timeout long-running blocks
Synopsis
require 'timeout'
status = Timeout::timeout(5) {
# Something that should be interrupted if it takes more than 5 seconds...
}
Description
Timeout provides a way to auto-terminate a potentially long-running operation if it hasn’t finished in a fixed amount of time.
Previous versions didn’t use a module for namespacing, however #timeout is provided for backwards compatibility. You should prefer Timeout.timeout instead.
Copyright
Copyright:
(C) 2000 Network Applied Communication Laboratory, Inc.
Copyright:
(C) 2000 Information-technology Promotion Agency, Japan
Constants:
VERSION:
[not documented]
Class methods:
timeout
Instance methods:
timeout
errno #
Errno
(from ruby core)
Ruby exception objects are subclasses of Exception. However, operating systems typically report errors using plain integers. Module Errno is created dynamically to map these operating system errors to Ruby classes, with each error number generating its own subclass of SystemCallError. As the subclass is created in module Errno, its name will start Errno::
.
The names of the Errno::
classes depend on the environment in which Ruby runs. On a typical Unix or Windows platform, there are Errno classes such as Errno::EACCES, Errno::EAGAIN, Errno::EINTR, and so on.
The integer operating system error number corresponding to a particular error is available as the class constant Errno::
error::Errno
.
Errno::EACCES::Errno #=> 13
Errno::EAGAIN::Errno #=> 11
Errno::EINTR::Errno #=> 4
The full list of operating system errors on your particular platform are available as the constants of Errno.
Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ...
which #
MakeMakefile#find_executable
(from ruby core)
find_executable(bin, path = nil)
Searches for the executable bin
on path
. The default path is your PATH
environment variable. If that isn’t defined, it will resort to searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
If found, it will return the full path, including the executable name, of where it was found.
Note that this method does not actually affect the generated Makefile.
curl wget #
curl
commands to Ruby's code.
require 'open-uri'
URI.open('http://example.com').read
# Download a file:
URI.open('http://example.com').then { IO.copy_stream _1, 'path/to/file' }
tput #
Equivalent Ruby gem: tty-cursor
nohup #
Kernel#fork
(from ruby core)
Kernel.fork [{ block }] -> integer or nil
Process.fork [{ block }] -> integer or nil
Creates a subprocess. If a block is specified, that block is run in the subprocess, and the subprocess terminates with a status of zero. Otherwise, the fork
call returns twice, once in the parent, returning the process ID of the child, and once in the child, returning nil. The child process can exit using Kernel.exit! to avoid running any at_exit
functions. The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.
The thread calling fork is the only thread in the created child process. fork doesn’t copy other threads.
If fork is not usable, Process.respond_to?(:fork) returns false.
Note that fork(2) is not available on some platforms like Windows and NetBSD 4. Therefore you should use spawn() instead of fork().
Data Processing
head #
Array#first
(from ruby core)
array.first -> object or nil
array.first(n) -> new_array
Returns elements from self
; does not modify self
.
When no argument is given, returns the first element:
a = [:foo, 'bar', 2]
a.first # => :foo
a # => [:foo, "bar", 2]
If self
is empty, returns nil
.
When non-negative Integer argument n
is given, returns the first n
elements in a new Array:
a = [:foo, 'bar', 2]
a.first(2) # => [:foo, "bar"]
If n >= array.size
, returns all elements:
a = [:foo, 'bar', 2]
a.first(50) # => [:foo, "bar", 2]
If n == 0
returns an new empty Array:
a = [:foo, 'bar', 2]
a.first(0) # []
Related: #last.
tail #
Array#last
(from ruby core)
array.last -> object or nil
array.last(n) -> new_array
Returns elements from self
; self
is not modified.
When no argument is given, returns the last element:
a = [:foo, 'bar', 2]
a.last # => 2
a # => [:foo, "bar", 2]
If self
is empty, returns nil
.
When non-negative Integer argument n
is given, returns the last n
elements in a new Array:
a = [:foo, 'bar', 2]
a.last(2) # => ["bar", 2]
If n >= array.size
, returns all elements:
a = [:foo, 'bar', 2]
a.last(50) # => [:foo, "bar", 2]
If n == 0
, returns an new empty Array:
a = [:foo, 'bar', 2]
a.last(0) # []
Related: #first.
sort #
Array#sort
(from ruby core)
array.sort -> new_array
array.sort {|a, b| ... } -> new_array
Returns a new Array whose elements are those from self
, sorted.
With no block, compares elements using operator <=>
(see Comparable):
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort
a1 # => ["a", "b", "c", "d", "e"]
With a block, calls the block with each element pair; for each element pair a
and b
, the block should return an integer:
-
Negative when
b
is to followa
. -
Zero when
a
andb
are equivalent. -
Positive when
a
is to followb
.
Example:
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort {|a, b| a <=> b }
a1 # => ["a", "b", "c", "d", "e"]
a2 = a.sort {|a, b| b <=> a }
a2 # => ["e", "d", "c", "b", "a"]
When the block returns zero, the order for a
and b
is indeterminate, and may be unstable:
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort {|a, b| 0 }
a1 # => ["c", "e", "b", "d", "a"]
Related: Enumerable#sort_by.
rev tac #
String#reverse
(from ruby core)
reverse -> string
Returns a new string with the characters from self
in reverse order.
'stressed'.reverse # => "desserts"
Array#reverse
(from ruby core)
array.reverse -> new_array
Returns a new Array with the elements of self
in reverse order:
a = ['foo', 'bar', 'two']
a1 = a.reverse
a1 # => ["two", "bar", "foo"]
shuf #
Array#shuffle
(from ruby core)
array.shuffle(random: Random) -> new_ary
Returns a new array with elements of self
shuffled.
a = [1, 2, 3] #=> [1, 2, 3]
a.shuffle #=> [2, 3, 1]
a #=> [1, 2, 3]
The optional random
argument will be used as the random number generator:
a.shuffle(random: Random.new(1)) #=> [1, 3, 2]
uniq #
Array#uniq
(from ruby core)
array.uniq -> new_array
array.uniq {|element| ... } -> new_array
Returns a new Array containing those elements from self
that are not duplicates, the first occurrence always being retained.
With no block given, identifies and omits duplicates using method eql?
to compare:
a = [0, 0, 1, 1, 2, 2]
a.uniq # => [0, 1, 2]
With a block given, calls the block for each element; identifies (using method eql?
) and omits duplicate values, that is, those elements for which the block returns the same value:
a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
split csplit #
Enumerable#each_slice
(from ruby core)
each_slice(n) { ... } -> self
each_slice(n) -> enumerator
Calls the block with each successive disjoint n
-tuple of elements; returns self
:
a = []
(1..10).each_slice(3) {|tuple| a.push(tuple) }
a # => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
a = []
h = {foo: 0, bar: 1, baz: 2, bat: 3, bam: 4}
h.each_slice(2) {|tuple| a.push(tuple) }
a # => [[[:foo, 0], [:bar, 1]], [[:baz, 2], [:bat, 3]], [[:bam, 4]]]
With no block given, returns an Enumerator.
wc #
Array#size
(from ruby core)
size()
Returns the count of elements in self
.
(This method is an alias for Array#length.)
Returns the count of elements in self
.
chars_count = 'string'.chars.size
words_count = 'Hello, World!'.split.size
lines_count = "1\n2\n3".lines.size
tr #
String#tr
(from ruby core)
tr(selector, replacements) -> new_string
Returns a copy of self
with each character specified by string selector
translated to the corresponding character in string replacements
. The correspondence is positional:
-
Each occurrence of the first character specified by
selector
is translated to the first character inreplacements
. -
Each occurrence of the second character specified by
selector
is translated to the second character inreplacements
. -
And so on.
Example:
'hello'.tr('el', 'ip') #=> "hippo"
If replacements
is shorter than selector
, it is implicitly padded with its own last character:
'hello'.tr('aeiou', '-') # => "h-ll-"
'hello'.tr('aeiou', 'AA-') # => "hAll-"
Arguments selector
and replacements
must be valid character selectors (see Character Selectors), and may use any of its valid forms, including negation, ranges, and escaping:
# Negation.
'hello'.tr('^aeiou', '-') # => "-e--o"
# Ranges.
'ibm'.tr('b-z', 'a-z') # => "hal"
# Escapes.
'hel^lo'.tr('\^aeiou', '-') # => "h-l-l-" # Escaped leading caret.
'i-b-m'.tr('b\-z', 'a-z') # => "ibabm" # Escaped embedded hyphen.
'foo\\bar'.tr('ab\\', 'XYZ') # => "fooZYXr" # Escaped backslash.
cut #
Array#[]
(from ruby core)
array[index] -> object or nil
array[start, length] -> object or nil
array[range] -> object or nil
array[aseq] -> object or nil
array.slice(index) -> object or nil
array.slice(start, length) -> object or nil
array.slice(range) -> object or nil
array.slice(aseq) -> object or nil
Returns elements from self
; does not modify self
.
When a single Integer argument index
is given, returns the element at offset index
:
a = [:foo, 'bar', 2]
a[0] # => :foo
a[2] # => 2
a # => [:foo, "bar", 2]
If index
is negative, counts relative to the end of self
:
a = [:foo, 'bar', 2]
a[-1] # => 2
a[-2] # => "bar"
If index
is out of range, returns nil
.
When two Integer arguments start
and length
are given, returns a new Array of size length
containing successive elements beginning at offset start
:
a = [:foo, 'bar', 2]
a[0, 2] # => [:foo, "bar"]
a[1, 2] # => ["bar", 2]
If start + length
is greater than self.length
, returns all elements from offset start
to the end:
a = [:foo, 'bar', 2]
a[0, 4] # => [:foo, "bar", 2]
a[1, 3] # => ["bar", 2]
a[2, 2] # => [2]
If start == self.size
and length >= 0
, returns a new empty Array.
If length
is negative, returns nil
.
When a single Range argument range
is given, treats range.min
as start
above and range.size
as length
above:
a = [:foo, 'bar', 2]
a[0..1] # => [:foo, "bar"]
a[1..2] # => ["bar", 2]
Special case: If range.start == a.size
, returns a new empty Array.
If range.end
is negative, calculates the end index from the end:
a = [:foo, 'bar', 2]
a[0..-1] # => [:foo, "bar", 2]
a[0..-2] # => [:foo, "bar"]
a[0..-3] # => [:foo]
If range.start
is negative, calculates the start index from the end:
a = [:foo, 'bar', 2]
a[-1..2] # => [2]
a[-2..2] # => ["bar", 2]
a[-3..2] # => [:foo, "bar", 2]
If range.start
is larger than the array size, returns nil
.
a = [:foo, 'bar', 2]
a[4..1] # => nil
a[4..0] # => nil
a[4..-1] # => nil
When a single Enumerator::ArithmeticSequence argument aseq
is given, returns an Array of elements corresponding to the indexes produced by the sequence.
a = ['--', 'data1', '--', 'data2', '--', 'data3']
a[(1..).step(2)] # => ["data1", "data2", "data3"]
Unlike slicing with range, if the start or the end of the arithmetic sequence is larger than array size, throws RangeError.
a = ['--', 'data1', '--', 'data2', '--', 'data3']
a[(1..11).step(2)]
# RangeError (((1..11).step(2)) out of range)
a[(7..).step(2)]
# RangeError (((7..).step(2)) out of range)
If given a single argument, and its type is not one of the listed, tries to convert it to Integer, and raises if it is impossible:
a = [:foo, 'bar', 2]
# Raises TypeError (no implicit conversion of Symbol into Integer):
a[:foo]
Array#slice is an alias for Array#[].
join paste pr #
Array#transpose
(from ruby core)
array.transpose -> new_array
Transposes the rows and columns in an Array of Arrays; the nested Arrays must all be the same size:
a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
Array#zip
(from ruby core)
array.zip(*other_arrays) -> new_array
array.zip(*other_arrays) {|other_array| ... } -> nil
When no block given, returns a new Array new_array
of size self.size
whose elements are Arrays.
Each nested array new_array[n]
is of size other_arrays.size+1
, and contains:
-
The nth element of
self
. -
The nth element of each of the
other_arrays
.
If all other_arrays
and self
are the same size:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
If any array in other_arrays
is smaller than self
, fills to self.size
with nil
:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2]
c = [:c0, :c1]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]]
If any array in other_arrays
is larger than self
, its trailing elements are ignored:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3, :b4]
c = [:c0, :c1, :c2, :c3, :c4, :c5]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
When a block is given, calls the block with each of the sub-arrays (formed as above); returns nil
:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
a.zip(b, c) {|sub_array| p sub_array} # => nil
Output:
[:a0, :b0, :c0]
[:a1, :b1, :c1]
[:a2, :b2, :c2]
[:a3, :b3, :c3]
combine #
file1 = File.readlines('path/to/file1', chomp: true) # Get array of lines in file1
file2 = File.readlines('path/to/file1', chomp: true) # Get array of lines in file2
combine_and = file1 & file2 # Outputs lines that are in file1 if they are also present in file2.
combine_not = file1 - file2 # Outputs lines that are in file1 but not in file2.
combine_or = file1 | file2 # Outputs lines that are in file1 or file2.
combine_xor = combine_or - combine_and # Outputs lines that are in either file1 or file2, but not in both files.
grep #
Enumerable#grep
(from ruby core)
grep(pattern) -> array
grep(pattern) {|element| ... } -> array
Returns an array of objects based elements of self
that match the given pattern.
With no block given, returns an array containing each element for which pattern === element
is true
:
a = ['foo', 'bar', 'car', 'moo']
a.grep(/ar/) # => ["bar", "car"]
(1..10).grep(3..8) # => [3, 4, 5, 6, 7, 8]
['a', 'b', 0, 1].grep(Integer) # => [0, 1]
With a block given, calls the block with each matching element and returns an array containing each object returned by the block:
a = ['foo', 'bar', 'car', 'moo']
a.grep(/ar/) {|element| element.upcase } # => ["BAR", "CAR"]
Related: #grep_v.
sed #
String#sub
(from ruby core)
sub(pattern, replacement) -> new_string
sub(pattern) {|match| ... } -> new_string
Returns a copy of self
with only the first occurrence (not all occurrences) of the given pattern
replaced.
See Substitution Methods.
Related: String#sub!, String#gsub, String#gsub!.
String#gsub
(from ruby core)
gsub(pattern, replacement) -> new_string
gsub(pattern) {|match| ... } -> new_string
gsub(pattern) -> enumerator
Returns a copy of self
with all occurrences of the given pattern
replaced.
See Substitution Methods.
Returns an Enumerator if no replacement
and no block given.
Related: String#sub, String#sub!, String#gsub!.
awk #
ascii #
String#ord
(from ruby core)
ord -> integer
Returns the integer ordinal of the first character of self
:
'h'.ord # => 104
'hello'.ord # => 104
'тест'.ord # => 1090
'こんにちは'.ord # => 12371
od xxd hexdump #
Integer#to_s
(from ruby core)
to_s(base = 10) -> string
Returns a string containing the place-value representation of self
in radix base
(in 2..36).
12345.to_s # => "12345"
12345.to_s(2) # => "11000000111001"
12345.to_s(8) # => "30071"
12345.to_s(10) # => "12345"
12345.to_s(16) # => "3039"
12345.to_s(36) # => "9ix"
78546939656932.to_s(36) # => "rubyrules"
Raises an exception if base
is out of range.
Integer#inspect is an alias for Integer#to_s.
String#to_i
(from ruby core)
to_i(base = 10) -> integer
Returns the result of interpreting leading characters in self
as an integer in the given base
(which must be in (0, 2..36)):
'123456'.to_i # => 123456
'123def'.to_i(16) # => 1195503
With base
zero, string object
may contain leading characters to specify the actual base:
'123def'.to_i(0) # => 123
'0123def'.to_i(0) # => 83
'0b123def'.to_i(0) # => 1
'0o123def'.to_i(0) # => 83
'0d123def'.to_i(0) # => 123
'0x123def'.to_i(0) # => 1195503
Characters past a leading valid number (in the given base
) are ignored:
'12.345'.to_i # => 12
'12345'.to_i(2) # => 1
Returns zero if there is no leading valid number:
'abcdef'.to_i # => 0
'2'.to_i(2) # => 0
ifne #
String#empty?
(from ruby core)
empty? -> true or false
Returns true
if the length of self
is zero, false
otherwise:
"hello".empty? # => false
" ".empty? # => false
"".empty? # => true
iconv #
String#encode
(from ruby core)
encode(dst_encoding = Encoding.default_internal, **enc_opts) -> string
encode(dst_encoding, src_encoding, **enc_opts) -> string
Returns a copy of self
transcoded as determined by dst_encoding
. By default, raises an exception if self
contains an invalid byte or a character not defined in dst_encoding
; that behavior may be modified by encoding options; see below.
With no arguments:
-
Uses the same encoding if
Encoding.default_internal
isnil
(the default):Encoding.default_internal # => nil s = "Ruby\x99".force_encoding('Windows-1252') s.encoding # => #<Encoding:Windows-1252> s.bytes # => [82, 117, 98, 121, 153] t = s.encode # => "Ruby\x99" t.encoding # => #<Encoding:Windows-1252> t.bytes # => [82, 117, 98, 121, 226, 132, 162]
-
Otherwise, uses the encoding
Encoding.default_internal
:Encoding.default_internal = 'UTF-8' t = s.encode # => "Ruby™" t.encoding # => #<Encoding:UTF-8>
With only argument dst_encoding
given, uses that encoding:
s = "Ruby\x99".force_encoding('Windows-1252')
s.encoding # => #<Encoding:Windows-1252>
t = s.encode('UTF-8') # => "Ruby™"
t.encoding # => #<Encoding:UTF-8>
With arguments dst_encoding
and src_encoding
given, interprets self
using src_encoding
, encodes the new string using dst_encoding
:
s = "Ruby\x99"
t = s.encode('UTF-8', 'Windows-1252') # => "Ruby™"
t.encoding # => #<Encoding:UTF-8>
Optional keyword arguments enc_opts
specify encoding options; see Encoding Options.
isutf8 #
String#isutf8
(from ruby core)
String#isutf8 => true or false
Returns whether self
‘s encoding is UTF-8 or not.
jq #
JSON
(from ruby core)
JavaScript Object Notation (JSON)
JSON is a lightweight data-interchange format.
A JSON value is one of the following:
-
Double-quoted text:
"foo"
. -
Number:
1
,1.0
,2.0e2
. -
Boolean:
true
,false
. -
Null:
null
. -
Array: an ordered list of values, enclosed by square brackets:
["foo", 1, 1.0, 2.0e2, true, false, null]
-
Object: a collection of name/value pairs, enclosed by curly braces; each name is double-quoted text; the values may be any JSON values:
{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}
A JSON array or object may contain nested arrays, objects, and scalars to any depth:
{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}
[{"foo": 0, "bar": 1}, ["baz", 2]]
Using Module JSON
To make module JSON available in your code, begin with:
require 'json'
All examples here assume that this has been done.
Parsing JSON
You can parse a String containing JSON data using either of two methods:
-
JSON.parse(source, opts)
-
JSON.parse!(source, opts)
where
-
source
is a Ruby object. -
opts
is a Hash object containing options that control both input allowed and output formatting.
The difference between the two methods is that JSON.parse! omits some checks and may not be safe for some source
data; use it only for data from trusted sources. Use the safer method JSON.parse for less trusted sources.
Parsing JSON Arrays
When source
is a JSON array, JSON.parse by default returns a Ruby Array:
json = '["foo", 1, 1.0, 2.0e2, true, false, null]'
ruby = JSON.parse(json)
ruby # => ["foo", 1, 1.0, 200.0, true, false, nil]
ruby.class # => Array
The JSON array may contain nested arrays, objects, and scalars to any depth:
json = '[{"foo": 0, "bar": 1}, ["baz", 2]]'
JSON.parse(json) # => [{"foo"=>0, "bar"=>1}, ["baz", 2]]
Parsing JSON Objects
When the source is a JSON object, JSON.parse by default returns a Ruby Hash:
json = '{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}'
ruby = JSON.parse(json)
ruby # => {"a"=>"foo", "b"=>1, "c"=>1.0, "d"=>200.0, "e"=>true, "f"=>false, "g"=>nil}
ruby.class # => Hash
The JSON object may contain nested arrays, objects, and scalars to any depth:
json = '{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}'
JSON.parse(json) # => {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]}
Parsing JSON Scalars
When the source is a JSON scalar (not an array or object), JSON.parse returns a Ruby scalar.
String:
ruby = JSON.parse('"foo"')
ruby # => 'foo'
ruby.class # => String
Integer:
ruby = JSON.parse('1')
ruby # => 1
ruby.class # => Integer
Float:
ruby = JSON.parse('1.0')
ruby # => 1.0
ruby.class # => Float
ruby = JSON.parse('2.0e2')
ruby # => 200
ruby.class # => Float
Boolean:
ruby = JSON.parse('true')
ruby # => true
ruby.class # => TrueClass
ruby = JSON.parse('false')
ruby # => false
ruby.class # => FalseClass
Null:
ruby = JSON.parse('null')
ruby # => nil
ruby.class # => NilClass
Parsing Options
Input Options
Option max_nesting
(Integer) specifies the maximum nesting depth allowed; defaults to 100
; specify false
to disable depth checking.
With the default, false
:
source = '[0, [1, [2, [3]]]]'
ruby = JSON.parse(source)
ruby # => [0, [1, [2, [3]]]]
Too deep:
# Raises JSON::NestingError (nesting of 2 is too deep):
JSON.parse(source, {max_nesting: 1})
Bad value:
# Raises TypeError (wrong argument type Symbol (expected Fixnum)):
JSON.parse(source, {max_nesting: :foo})
Option allow_nan
(boolean) specifies whether to allow NaN, Infinity, and MinusInfinity in source
; defaults to false
.
With the default, false
:
# Raises JSON::ParserError (225: unexpected token at '[NaN]'):
JSON.parse('[NaN]')
# Raises JSON::ParserError (232: unexpected token at '[Infinity]'):
JSON.parse('[Infinity]')
# Raises JSON::ParserError (248: unexpected token at '[-Infinity]'):
JSON.parse('[-Infinity]')
Allow:
source = '[NaN, Infinity, -Infinity]'
ruby = JSON.parse(source, {allow_nan: true})
ruby # => [NaN, Infinity, -Infinity]
Output Options
Option symbolize_names
(boolean) specifies whether returned Hash keys should be Symbols; defaults to false
(use Strings).
With the default, false
:
source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
ruby = JSON.parse(source)
ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}
Use Symbols:
ruby = JSON.parse(source, {symbolize_names: true})
ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil}
Option object_class
(Class) specifies the Ruby class to be used for each JSON object; defaults to Hash.
With the default, Hash:
source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
ruby = JSON.parse(source)
ruby.class # => Hash
Use class OpenStruct:
ruby = JSON.parse(source, {object_class: OpenStruct})
ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>
Option array_class
(Class) specifies the Ruby class to be used for each JSON array; defaults to Array.
With the default, Array:
source = '["foo", 1.0, true, false, null]'
ruby = JSON.parse(source)
ruby.class # => Array
Use class Set:
ruby = JSON.parse(source, {array_class: Set})
ruby # => #<Set: {"foo", 1.0, true, false, nil}>
Option create_additions
(boolean) specifies whether to use JSON additions in parsing. See JSON Additions.
Generating JSON
To generate a Ruby String containing JSON data, use method JSON.generate(source, opts)
, where
-
source
is a Ruby object. -
opts
is a Hash object containing options that control both input allowed and output formatting.
Generating JSON from Arrays
When the source is a Ruby Array, JSON.generate returns a String containing a JSON array:
ruby = [0, 's', :foo]
json = JSON.generate(ruby)
json # => '[0,"s","foo"]'
The Ruby Array array may contain nested arrays, hashes, and scalars to any depth:
ruby = [0, [1, 2], {foo: 3, bar: 4}]
json = JSON.generate(ruby)
json # => '[0,[1,2],{"foo":3,"bar":4}]'
Generating JSON from Hashes
When the source is a Ruby Hash, JSON.generate returns a String containing a JSON object:
ruby = {foo: 0, bar: 's', baz: :bat}
json = JSON.generate(ruby)
json # => '{"foo":0,"bar":"s","baz":"bat"}'
The Ruby Hash array may contain nested arrays, hashes, and scalars to any depth:
ruby = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
json = JSON.generate(ruby)
json # => '{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}'
Generating JSON from Other Objects
When the source is neither an Array nor a Hash, the generated JSON data depends on the class of the source.
When the source is a Ruby Integer or Float, JSON.generate returns a String containing a JSON number:
JSON.generate(42) # => '42'
JSON.generate(0.42) # => '0.42'
When the source is a Ruby String, JSON.generate returns a String containing a JSON string (with double-quotes):
JSON.generate('A string') # => '"A string"'
When the source is true
, false
or nil
, JSON.generate returns a String containing the corresponding JSON token:
JSON.generate(true) # => 'true'
JSON.generate(false) # => 'false'
JSON.generate(nil) # => 'null'
When the source is none of the above, JSON.generate returns a String containing a JSON string representation of the source:
JSON.generate(:foo) # => '"foo"'
JSON.generate(Complex(0, 0)) # => '"0+0i"'
JSON.generate(Dir.new('.')) # => '"#<Dir>"'
Generating Options
Input Options
Option allow_nan
(boolean) specifies whether NaN
, Infinity
, and -Infinity
may be generated; defaults to false
.
With the default, false
:
# Raises JSON::GeneratorError (920: NaN not allowed in JSON):
JSON.generate(JSON::NaN)
# Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
JSON.generate(JSON::Infinity)
# Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
JSON.generate(JSON::MinusInfinity)
Allow:
ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
Option max_nesting
(Integer) specifies the maximum nesting depth in obj
; defaults to 100
.
With the default, 100
:
obj = [[[[[[0]]]]]]
JSON.generate(obj) # => '[[[[[[0]]]]]]'
Too deep:
# Raises JSON::NestingError (nesting of 2 is too deep):
JSON.generate(obj, max_nesting: 2)
Output Options
The default formatting options generate the most compact JSON data, all on one line and with no whitespace.
You can use these formatting options to generate JSON data in a more open format, using whitespace. See also JSON.pretty_generate.
-
Option
array_nl
(String) specifies a string (usually a newline) to be inserted after each JSON array; defaults to the empty String,''
. -
Option
object_nl
(String) specifies a string (usually a newline) to be inserted after each JSON object; defaults to the empty String,''
. -
Option
indent
(String) specifies the string (usually spaces) to be used for indentation; defaults to the empty String,''
; defaults to the empty String,''
; has no effect unless optionsarray_nl
orobject_nl
specify newlines. -
Option
space
(String) specifies a string (usually a space) to be inserted after the colon in each JSON object’s pair; defaults to the empty String,''
. -
Option
space_before
(String) specifies a string (usually a space) to be inserted before the colon in each JSON object’s pair; defaults to the empty String,''
.
In this example, obj
is used first to generate the shortest JSON data (no whitespace), then again with all formatting options specified:
obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
json = JSON.generate(obj)
puts 'Compact:', json
opts = {
array_nl: "\n",
object_nl: "\n",
indent: ' ',
space_before: ' ',
space: ' '
}
puts 'Open:', JSON.generate(obj, opts)
Output:
Compact:
{"foo":["bar","baz"],"bat":{"bam":0,"bad":1}}
Open:
{
"foo" : [
"bar",
"baz"
],
"bat" : {
"bam" : 0,
"bad" : 1
}
}
JSON Additions
When you “round trip” a non-String object from Ruby to JSON and back, you have a new String, instead of the object you began with:
ruby0 = Range.new(0, 2)
json = JSON.generate(ruby0)
json # => '0..2"'
ruby1 = JSON.parse(json)
ruby1 # => '0..2'
ruby1.class # => String
You can use JSON additions to preserve the original object. The addition is an extension of a ruby class, so that:
-
JSON.generate stores more information in the JSON string.
-
JSON.parse, called with option
create_additions
, uses that information to create a proper Ruby object.
This example shows a Range being generated into JSON and parsed back into Ruby, both without and with the addition for Range:
ruby = Range.new(0, 2)
# This passage does not use the addition for Range.
json0 = JSON.generate(ruby)
ruby0 = JSON.parse(json0)
# This passage uses the addition for Range.
require 'json/add/range'
json1 = JSON.generate(ruby)
ruby1 = JSON.parse(json1, create_additions: true)
# Make a nice display.
display = <<EOT
Generated JSON:
Without addition: #{json0} (#{json0.class})
With addition: #{json1} (#{json1.class})
Parsed JSON:
Without addition: #{ruby0.inspect} (#{ruby0.class})
With addition: #{ruby1.inspect} (#{ruby1.class})
EOT
puts display
This output shows the different results:
Generated JSON:
Without addition: "0..2" (String)
With addition: {"json_class":"Range","a":[0,2,false]} (String)
Parsed JSON:
Without addition: "0..2" (String)
With addition: 0..2 (Range)
The JSON module includes additions for certain classes. You can also craft custom additions. See Custom JSON Additions.
Built-in Additions
The JSON module includes additions for certain classes. To use an addition, require
its source:
-
BigDecimal:
require 'json/add/bigdecimal'
-
Complex:
require 'json/add/complex'
-
Date:
require 'json/add/date'
-
DateTime:
require 'json/add/date_time'
-
Exception:
require 'json/add/exception'
-
OpenStruct:
require 'json/add/ostruct'
-
Range:
require 'json/add/range'
-
Rational:
require 'json/add/rational'
-
Regexp:
require 'json/add/regexp'
-
Set:
require 'json/add/set'
-
Struct:
require 'json/add/struct'
-
Symbol:
require 'json/add/symbol'
-
Time:
require 'json/add/time'
To reduce punctuation clutter, the examples below show the generated JSON via puts
, rather than the usual inspect
,
BigDecimal:
require 'json/add/bigdecimal'
ruby0 = BigDecimal(0) # 0.0
json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
ruby1 = JSON.parse(json, create_additions: true) # 0.0
ruby1.class # => BigDecimal
Complex:
require 'json/add/complex'
ruby0 = Complex(1+0i) # 1+0i
json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
ruby1 = JSON.parse(json, create_additions: true) # 1+0i
ruby1.class # Complex
Date:
require 'json/add/date'
ruby0 = Date.today # 2020-05-02
json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
ruby1.class # Date
DateTime:
require 'json/add/date_time'
ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
json = JSON.generate(ruby0) # {"json_class":"DateTime","y":2020,"m":5,"d":2,"H":10,"M":38,"S":13,"of":"-5/24","sg":2299161.0}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
ruby1.class # DateTime
Exception (and its subclasses including RuntimeError):
require 'json/add/exception'
ruby0 = Exception.new('A message') # A message
json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
ruby1 = JSON.parse(json, create_additions: true) # A message
ruby1.class # Exception
ruby0 = RuntimeError.new('Another message') # Another message
json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
ruby1 = JSON.parse(json, create_additions: true) # Another message
ruby1.class # RuntimeError
OpenStruct:
require 'json/add/ostruct'
ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
ruby1.class # OpenStruct
Range:
require 'json/add/range'
ruby0 = Range.new(0, 2) # 0..2
json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
ruby1 = JSON.parse(json, create_additions: true) # 0..2
ruby1.class # Range
Rational:
require 'json/add/rational'
ruby0 = Rational(1, 3) # 1/3
json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
ruby1 = JSON.parse(json, create_additions: true) # 1/3
ruby1.class # Rational
Regexp:
require 'json/add/regexp'
ruby0 = Regexp.new('foo') # (?-mix:foo)
json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
ruby1.class # Regexp
Set:
require 'json/add/set'
ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
ruby1.class # Set
Struct:
require 'json/add/struct'
Customer = Struct.new(:name, :address) # Customer
ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
ruby1.class # Customer
Symbol:
require 'json/add/symbol'
ruby0 = :foo # foo
json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
ruby1 = JSON.parse(json, create_additions: true) # foo
ruby1.class # Symbol
Time:
require 'json/add/time'
ruby0 = Time.now # 2020-05-02 11:28:26 -0500
json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
ruby1.class # Time
Custom JSON Additions
In addition to the JSON additions provided, you can craft JSON additions of your own, either for Ruby built-in classes or for user-defined classes.
Here’s a user-defined class Foo
:
class Foo
attr_accessor :bar, :baz
def initialize(bar, baz)
self.bar = bar
self.baz = baz
end
end
Here’s the JSON addition for it:
# Extend class Foo with JSON addition.
class Foo
# Serialize Foo object with its class name and arguments
def to_json(*args)
{
JSON.create_id => self.class.name,
'a' => [ bar, baz ]
}.to_json(*args)
end
# Deserialize JSON string by constructing new Foo object with arguments.
def self.json_create(object)
new(*object['a'])
end
end
Demonstration:
require 'json'
# This Foo object has no custom addition.
foo0 = Foo.new(0, 1)
json0 = JSON.generate(foo0)
obj0 = JSON.parse(json0)
# Lood the custom addition.
require_relative 'foo_addition'
# This foo has the custom addition.
foo1 = Foo.new(0, 1)
json1 = JSON.generate(foo1)
obj1 = JSON.parse(json1, create_additions: true)
# Make a nice display.
display = <<EOT
Generated JSON:
Without custom addition: #{json0} (#{json0.class})
With custom addition: #{json1} (#{json1.class})
Parsed JSON:
Without custom addition: #{obj0.inspect} (#{obj0.class})
With custom addition: #{obj1.inspect} (#{obj1.class})
EOT
puts display
Output:
Generated JSON:
Without custom addition: "#<Foo:0x0000000006534e80>" (String)
With custom addition: {"json_class":"Foo","a":[0,1]} (String)
Parsed JSON:
Without custom addition: "#<Foo:0x0000000006534e80>" (String)
With custom addition: #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)
Constants:
CREATE_ID_TLS_KEY:
[not documented]
DEFAULT_CREATE_ID:
[not documented]
Infinity:
[not documented]
JSON_LOADED:
[not documented]
MinusInfinity:
[not documented]
NaN:
[not documented]
VERSION:
JSON version
Class methods:
[]
create_fast_state
create_id
create_id=
create_pretty_state
dump_default_options
generator
iconv
load_default_options
parser
restore
state
Instance methods:
dump
fast_generate
generate
load
load_file
load_file!
parse
parse!
pretty_generate
restore
Attributes:
attr_accessor dump_default_options
attr_accessor load_default_options
attr_accessor state
attr_reader generator
attr_reader parser
tsort #
TSort
(from ruby core)
TSort implements topological sorting using Tarjan’s algorithm for strongly connected components.
TSort is designed to be able to be used with any object which can be interpreted as a directed graph.
TSort requires two methods to interpret an object as a graph, tsort_each_node and tsort_each_child.
-
tsort_each_node is used to iterate for all nodes over a graph.
-
tsort_each_child is used to iterate for child nodes of a given node.
The equality of nodes are defined by eql? and hash since TSort uses Hash internally.
A Simple Example
The following example demonstrates how to mix the TSort module into an existing class (in this case, Hash). Here, we’re treating each key in the hash as a node in the graph, and so we simply alias the required #tsort_each_node method to Hash’s #each_key method. For each key in the hash, the associated value is an array of the node’s child nodes. This choice in turn leads to our implementation of the required #tsort_each_child method, which fetches the array of child nodes and then iterates over that array using the user-supplied block.
require 'tsort'
class Hash
include TSort
alias tsort_each_node each_key
def tsort_each_child(node, &block)
fetch(node).each(&block)
end
end
{1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
#=> [3, 2, 1, 4]
{1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
#=> [[4], [2, 3], [1]]
A More Realistic Example
A very simple ‘make’ like tool can be implemented as follows:
require 'tsort'
class Make
def initialize
@dep = {}
@dep.default = []
end
def rule(outputs, inputs=[], &block)
triple = [outputs, inputs, block]
outputs.each {|f| @dep[f] = [triple]}
@dep[triple] = inputs
end
def build(target)
each_strongly_connected_component_from(target) {|ns|
if ns.length != 1
fs = ns.delete_if {|n| Array === n}
raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
end
n = ns.first
if Array === n
outputs, inputs, block = n
inputs_time = inputs.map {|f| File.mtime f}.max
begin
outputs_time = outputs.map {|f| File.mtime f}.min
rescue Errno::ENOENT
outputs_time = nil
end
if outputs_time == nil ||
inputs_time != nil && outputs_time <= inputs_time
sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
block.call
end
end
}
end
def tsort_each_child(node, &block)
@dep[node].each(&block)
end
include TSort
end
def command(arg)
print arg, "\n"
system arg
end
m = Make.new
m.rule(%w[t1]) { command 'date > t1' }
m.rule(%w[t2]) { command 'date > t2' }
m.rule(%w[t3]) { command 'date > t3' }
m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
m.build('t5')
Bugs
-
‘tsort.rb’ is wrong name because this library uses Tarjan’s algorithm for strongly connected components. Although ‘strongly_connected_components.rb’ is correct but too long.
References
A. Tarjan, "Depth First Search and Linear Graph Algorithms",
SIAM Journal on Computing, Vol. 1, No. 2, pp. 146-160, June 1972.
Class methods:
each_strongly_connected_component
each_strongly_connected_component_from
strongly_connected_components
tsort
tsort_each
Instance methods:
each_strongly_connected_component
each_strongly_connected_component_from
strongly_connected_components
tsort
tsort_each
tsort_each_child
tsort_each_node
File System
find #
Dir::[]
(from ruby core)
Dir[ string [, string ...] [, base: path] [, sort: true] ] -> array
Equivalent to calling Dir.glob([
string,…], 0)
.
Find
(from ruby core)
The Find
module supports the top-down traversal of a set of file paths.
For example, to total the size of all files under your home directory, ignoring anything in a “dot” directory (e.g. $HOME/.ssh):
require 'find'
total_size = 0
Find.find(ENV["HOME"]) do |path|
if FileTest.directory?(path)
if File.basename(path).start_with?('.')
Find.prune # Don't look any further into this directory.
else
next
end
else
total_size += FileTest.size(path)
end
end
Class methods:
find
prune
Instance methods:
find
prune
ls dir vdir #
Dir::children
(from ruby core)
Dir.children( dirname ) -> array
Dir.children( dirname, encoding: enc ) -> array
Returns an array containing all of the filenames except for “.” and “..” in the given directory. Will raise a SystemCallError if the named directory doesn’t exist.
The optional encoding keyword argument specifies the encoding of the directory. If not specified, the filesystem encoding is used.
Dir.children("testdir") #=> ["config.h", "main.rb"]
stat #
File::Stat < Object
Includes:
Comparable (from ruby core)
(from ruby core)
Objects of class File::Stat encapsulate common status information for File objects. The information is recorded at the moment the File::Stat object is created; changes made to the file after that point will not be reflected. File::Stat objects are returned by IO#stat, File::stat, File#lstat, and File::lstat. Many of these methods return platform-specific values, and not all values are meaningful on all systems. See also Kernel#test.
Class methods:
new
Instance methods:
<=>
atime
birthtime
blksize
blockdev?
blocks
chardev?
ctime
dev
dev_major
dev_minor
directory?
executable?
executable_real?
file?
ftype
gid
grpowned?
ino
inspect
mode
mtime
nlink
owned?
pipe?
rdev
rdev_major
rdev_minor
readable?
readable_real?
setgid?
setuid?
size
size?
socket?
sticky?
symlink?
uid
world_readable?
world_writable?
writable?
writable_real?
zero?
realpath #
File::realpath
(from ruby core)
File.realpath(pathname [, dir_string]) -> real_pathname
Returns the real (absolute) pathname of pathname in the actual filesystem not containing symlinks or useless dots.
If dir_string is given, it is used as a base directory for interpreting relative pathname instead of the current directory.
All components of the pathname must exist when this method is called.
basename #
File::basename
(from ruby core)
File.basename(file_name [, suffix] ) -> base_name
Returns the last component of the filename given in file_name (after first stripping trailing separators), which can be formed using both File::SEPARATOR and File::ALT_SEPARATOR as the separator when File::ALT_SEPARATOR is not nil
. If suffix is given and present at the end of file_name, it is removed. If suffix is “.*”, any extension will be removed.
File.basename("/home/gumby/work/ruby.rb") #=> "ruby.rb"
File.basename("/home/gumby/work/ruby.rb", ".rb") #=> "ruby"
File.basename("/home/gumby/work/ruby.rb", ".*") #=> "ruby"
dirname #
File::dirname
(from ruby core)
File.dirname(file_name, level = 1) -> dir_name
Returns all components of the filename given in file_name except the last one (after first stripping trailing separators). The filename can be formed using both File::SEPARATOR and File::ALT_SEPARATOR as the separator when File::ALT_SEPARATOR is not nil
.
File.dirname("/home/gumby/work/ruby.rb") #=> "/home/gumby/work"
If level
is given, removes the last level
components, not only one.
File.dirname("/home/gumby/work/ruby.rb", 2) #=> "/home/gumby"
File.dirname("/home/gumby/work/ruby.rb", 4) #=> "/"
readlink #
File::readlink
(from ruby core)
File.readlink(link_name) -> file_name
Returns the name of the file referenced by the given link. Not available on all platforms.
File.symlink("testfile", "link2test") #=> 0
File.readlink("link2test") #=> "testfile"
cat #
File::read
(from ruby core)
Implementation from IO
IO.read(command, length = nil, offset = 0, **opts) -> string or nil
IO.read(path, length = nil, offset = 0, **opts) -> string or nil
Opens the stream, reads and returns some or all of its content, and closes the stream; returns nil
if no bytes were read.
When called from class IO (but not subclasses of IO), this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
The first argument must be a string; its meaning depends on whether it starts with the pipe character ('|'
):
-
If so (and if
self
is IO), the rest of the string is a command to be executed as a subprocess. -
Otherwise, the string is the path to a file.
With only argument command
given, executes the command in a shell, returns its entire $stdout:
IO.read('| cat t.txt')
# => "First line\nSecond line\n\nThird line\nFourth line\n"
With only argument path
given, reads in text mode and returns the entire content of the file at the given path:
IO.read('t.txt')
# => "First line\nSecond line\n\nThird line\nFourth line\n"
On Windows, text mode can terminate reading and leave bytes in the file unread when encountering certain special bytes. Consider using IO.binread if all bytes in the file should be read.
For both forms, command and path, the remaining arguments are the same.
With argument length
, returns length
bytes if available:
IO.read('t.txt', 7) # => "First l"
IO.read('t.txt', 700)
# => "First line\r\nSecond line\r\n\r\nFourth line\r\nFifth line\r\n"
With arguments length
and offset
, returns length
bytes if available, beginning at the given offset
:
IO.read('t.txt', 10, 2) # => "rst line\nS"
IO.read('t.txt', 10, 200) # => nil
Optional keyword arguments opts
specify:
touch #
FileUtils::touch
(from ruby core)
touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
Updates modification times (mtime) and access times (atime) of the entries given by the paths in list
(a single path or an array of paths); returns list
if it is an array, [list]
otherwise.
By default, creates an empty file for any path to a non-existent entry; use keyword argument nocreate
to raise an exception instead.
Argument list
or its elements should be interpretable as paths.
Examples:
# Single path.
f = File.new('src0.txt') # Existing file.
f.atime # => 2022-06-10 11:11:21.200277 -0700
f.mtime # => 2022-06-10 11:11:21.200277 -0700
FileUtils.touch('src0.txt')
f = File.new('src0.txt')
f.atime # => 2022-06-11 08:28:09.8185343 -0700
f.mtime # => 2022-06-11 08:28:09.8185343 -0700
# Array of paths.
FileUtils.touch(['src0.txt', 'src0.dat'])
Keyword arguments:
-
mtime: time
- sets the entry’s mtime to the given time, instead of the current time. -
nocreate: true
- raises an exception if the entry does not exist. -
noop: true
- does not touch entries; returnsnil
. -
verbose: true
- prints an equivalent command:FileUtils.touch('src0.txt', noop: true, verbose: true) FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true) FileUtils.touch(path, noop: true, verbose: true)
Output:
touch src0.txt touch src0.txt src0.dat touch src0.txt
Related: FileUtils.uptodate?.
mkdir #
FileUtils::mkdir
(from ruby core)
mkdir(list, mode: nil, noop: nil, verbose: nil)
Creates directories at the paths in the given list
(a single path or an array of paths); returns list
if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths.
With no keyword arguments, creates a directory at each path
in list
by calling: Dir.mkdir(path, mode)
; see Dir.mkdir:
FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"]
FileUtils.mkdir('tmp4') # => ["tmp4"]
Keyword arguments:
-
mode: mode
- also callsFile.chmod(mode, path)
; see File.chmod. -
noop: true
- does not create directories. -
verbose: true
- prints an equivalent command:FileUtils.mkdir(%w[tmp0 tmp1], verbose: true) FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
Output:
mkdir tmp0 tmp1 mkdir -m 700 tmp2 tmp3
Raises an exception if any path points to an existing file or directory, or if for any reason a directory cannot be created.
Related: FileUtils.mkdir_p.
mkfifo #
File::mkfifo
(from ruby core)
File.mkfifo(file_name, mode=0666) => 0
Creates a FIFO special file with name file_name. mode specifies the FIFO’s permissions. It is modified by the process’s umask in the usual way: the permissions of the created file are (mode & ~umask).
mktemp #
Tempfile::create
(from ruby core)
create(basename="", tmpdir=nil, mode: 0, **options) { |tmpfile| ... }
Creates a file in the underlying file system; returns a new File object based on that file.
With no block given and no arguments, creates and returns file whose:
-
Class is File (not Tempfile).
-
Directory is the system temporary directory (system-dependent).
-
Generated filename is unique in that directory.
-
Permissions are
0600
; see File Permissions. -
Mode is
'w+'
(read/write mode, positioned at the end).
With no block, the file is not removed automatically, and so should be explicitly removed.
Example:
f = Tempfile.create # => #<File:/tmp/20220505-9795-17ky6f6>
f.class # => File
f.path # => "/tmp/20220505-9795-17ky6f6"
f.stat.mode.to_s(8) # => "100600"
File.exist?(f.path) # => true
File.unlink(f.path)
File.exist?(f.path) # => false
Argument basename
, if given, may be one of:
-
A string: the generated filename begins with
basename
:Tempfile.create('foo') # => #<File:/tmp/foo20220505-9795-1gok8l9>
-
An array of two strings
[prefix, suffix]
: the generated filename begins withprefix
and ends withsuffix
:Tempfile.create(%w/foo .jpg/) # => #<File:/tmp/foo20220505-17839-tnjchh.jpg>
With arguments basename
and tmpdir
, the file is created in directory tmpdir
:
Tempfile.create('foo', '.') # => #<File:./foo20220505-9795-1emu6g8>
Keyword arguments mode
and options
are passed directly to method File.open:
-
The value given with
mode
must be an integer, and may be expressed as the logical OR of constants defined in File::Constants. -
For
options
, see Open Options.
With a block given, creates the file as above, passes it to the block, and returns the block’s value; before the return, the file object is closed and the underlying file is removed:
Tempfile.create {|file| file.path } # => "/tmp/20220505-9795-rkists"
Related: Tempfile.new.
cp #
FileUtils::cp
(from ruby core)
cp(src, dest, preserve: nil, noop: nil, verbose: nil)
Copies files.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths.
If src
is the path to a file and dest
is not the path to a directory, copies src
to dest
:
FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true
If src
is the path to a file and dest
is the path to a directory, copies src
to dest/src
:
FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true
If src
is an array of paths to files and dest
is the path to a directory, copies from each src
to dest
:
src_file_paths = ['src2.txt', 'src2.dat']
FileUtils.touch(src_file_paths)
FileUtils.mkdir('dest2')
FileUtils.cp(src_file_paths, 'dest2')
File.file?('dest2/src2.txt') # => true
File.file?('dest2/src2.dat') # => true
Keyword arguments:
-
preserve: true
- preserves file times. -
noop: true
- does not copy files. -
verbose: true
- prints an equivalent command:FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true) FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true) FileUtils.cp(src_file_paths, 'dest2', noop: true, verbose: true)
Output:
cp src0.txt dest0.txt cp src1.txt dest1 cp src2.txt src2.dat dest2
Raises an exception if src
is a directory.
FileUtils.copy is an alias for FileUtils.cp.
Related: methods for copying.
FileUtils::cp_lr
(from ruby core)
cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
Creates hard links.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths.
If src
is the path to a directory and dest
does not exist, creates links dest
and descendents pointing to src
and its descendents:
tree('src0')
# => src0
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
File.exist?('dest0') # => false
FileUtils.cp_lr('src0', 'dest0')
tree('dest0')
# => dest0
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
If src
and dest
are both paths to directories, creates links dest/src
and descendents pointing to src
and its descendents:
tree('src1')
# => src1
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
FileUtils.mkdir('dest1')
FileUtils.cp_lr('src1', 'dest1')
tree('dest1')
# => dest1
# `-- src1
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
If src
is an array of paths to entries and dest
is the path to a directory, for each path filepath
in src
, creates a link at dest/filepath
pointing to that path:
tree('src2')
# => src2
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
FileUtils.mkdir('dest2')
FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2')
tree('dest2')
# => dest2
# |-- sub0
# | |-- src0.txt
# | `-- src1.txt
# `-- sub1
# |-- src2.txt
# `-- src3.txt
Keyword arguments:
-
dereference_root: false
- ifsrc
is a symbolic link, does not dereference it. -
noop: true
- does not create links. -
remove_destination: true
- removesdest
before creating links. -
verbose: true
- prints an equivalent command:FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true) FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true) FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2', noop: true, verbose: true)
Output:
cp -lr src0 dest0 cp -lr src1 dest1 cp -lr src2/sub0 src2/sub1 dest2
Raises an exception if dest
is the path to an existing file or directory and keyword argument remove_destination: true
is not given.
Related: methods for copying.
FileUtils::cp_r
(from ruby core)
cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil)
Recursively copies files.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths.
The mode, owner, and group are retained in the copy; to change those, use FileUtils.install instead.
If src
is the path to a file and dest
is not the path to a directory, copies src
to dest
:
FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp_r('src0.txt', 'dest0.txt')
File.file?('dest0.txt') # => true
If src
is the path to a file and dest
is the path to a directory, copies src
to dest/src
:
FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp_r('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true
If src
is the path to a directory and dest
does not exist, recursively copies src
to dest
:
tree('src2')
# => src2
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
FileUtils.exist?('dest2') # => false
FileUtils.cp_r('src2', 'dest2')
tree('dest2')
# => dest2
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
If src
and dest
are paths to directories, recursively copies src
to dest/src
:
tree('src3')
# => src3
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
FileUtils.mkdir('dest3')
FileUtils.cp_r('src3', 'dest3')
tree('dest3')
# => dest3
# `-- src3
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
If src
is an array of paths and dest
is a directory, recursively copies from each path in src
to dest
; the paths in src
may point to files and/or directories.
Keyword arguments:
-
dereference_root: false
- ifsrc
is a symbolic link, does not dereference it. -
noop: true
- does not copy files. -
preserve: true
- preserves file times. -
remove_destination: true
- removesdest
before copying files. -
verbose: true
- prints an equivalent command:FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true) FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true) FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true) FileUtils.cp_r('src3', 'dest3', noop: true, verbose: true)
Output:
cp -r src0.txt dest0.txt cp -r src1.txt dest1 cp -r src2 dest2 cp -r src3 dest3
Raises an exception of src
is the path to a directory and dest
is the path to a file.
Related: methods for copying.
mv #
FileUtils::mv
(from ruby core)
mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
Moves entries.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths.
If src
and dest
are on different file systems, first copies, then removes src
.
May cause a local vulnerability if not called with keyword argument secure: true
; see Avoiding the TOCTTOU Vulnerability.
If src
is the path to a single file or directory and dest
does not exist, moves src
to dest
:
tree('src0')
# => src0
# |-- src0.txt
# `-- src1.txt
File.exist?('dest0') # => false
FileUtils.mv('src0', 'dest0')
File.exist?('src0') # => false
tree('dest0')
# => dest0
# |-- src0.txt
# `-- src1.txt
If src
is an array of paths to files and directories and dest
is the path to a directory, copies from each path in the array to dest
:
File.file?('src1.txt') # => true
tree('src1')
# => src1
# |-- src.dat
# `-- src.txt
Dir.empty?('dest1') # => true
FileUtils.mv(['src1.txt', 'src1'], 'dest1')
tree('dest1')
# => dest1
# |-- src1
# | |-- src.dat
# | `-- src.txt
# `-- src1.txt
Keyword arguments:
-
force: true
- if the move includes removingsrc
(that is, ifsrc
anddest
are on different file systems), ignores raised exceptions of StandardError and its descendants. -
noop: true
- does not move files. -
secure: true
- removessrc
securely; see details at FileUtils.remove_entry_secure. -
verbose: true
- prints an equivalent command:FileUtils.mv('src0', 'dest0', noop: true, verbose: true) FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
Output:
mv src0 dest0 mv src1.txt src1 dest1
FileUtils.move is an alias for FileUtils.mv.
rm #
FileUtils::rm
(from ruby core)
rm(list, force: nil, noop: nil, verbose: nil)
Removes entries at the paths in the given list
(a single path or an array of paths) returns list
, if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths.
With no keyword arguments, removes files at the paths given in list
:
FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]
Keyword arguments:
-
force: true
- ignores raised exceptions of StandardError and its descendants. -
noop: true
- does not remove files; returnsnil
. -
verbose: true
- prints an equivalent command:FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
Output:
rm src0.dat src0.txt
FileUtils.remove is an alias for FileUtils.rm.
Related: methods for deleting.
FileUtils::rm_f
(from ruby core)
rm_f(list, noop: nil, verbose: nil)
Equivalent to:
FileUtils.rm(list, force: true, **kwargs)
Argument list
(a single path or an array of paths) should be interpretable as paths.
See FileUtils.rm for keyword arguments.
FileUtils.safe_unlink is an alias for FileUtils.rm_f.
Related: methods for deleting.
FileUtils::rm_r
(from ruby core)
rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
Removes entries at the paths in the given list
(a single path or an array of paths); returns list
, if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths.
May cause a local vulnerability if not called with keyword argument secure: true
; see Avoiding the TOCTTOU Vulnerability.
For each file path, removes the file at that path:
FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm_r(['src0.dat', 'src0.txt'])
File.exist?('src0.txt') # => false
File.exist?('src0.dat') # => false
For each directory path, recursively removes files and directories:
tree('src1')
# => src1
# |-- dir0
# | |-- src0.txt
# | `-- src1.txt
# `-- dir1
# |-- src2.txt
# `-- src3.txt
FileUtils.rm_r('src1')
File.exist?('src1') # => false
Keyword arguments:
-
force: true
- ignores raised exceptions of StandardError and its descendants. -
noop: true
- does not remove entries; returnsnil
. -
secure: true
- removessrc
securely; see details at FileUtils.remove_entry_secure. -
verbose: true
- prints an equivalent command:FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true) FileUtils.rm_r('src1', noop: true, verbose: true)
Output:
rm -r src0.dat src0.txt rm -r src1
Related: methods for deleting.
FileUtils::rm_rf
(from ruby core)
rm_rf(list, noop: nil, verbose: nil, secure: nil)
Equivalent to:
FileUtils.rm_r(list, force: true, **kwargs)
Argument list
or its elements should be interpretable as paths.
May cause a local vulnerability if not called with keyword argument secure: true
; see Avoiding the TOCTTOU Vulnerability.
See FileUtils.rm_r for keyword arguments.
FileUtils.rmtree is an alias for FileUtils.rm_rf.
Related: methods for deleting.
rmdir #
FileUtils::rmdir
(from ruby core)
rmdir(list, parents: nil, noop: nil, verbose: nil)
Removes directories at the paths in the given list
(a single path or an array of paths); returns list
, if it is an array, [list]
otherwise.
Argument list
or its elements should be interpretable as paths.
With no keyword arguments, removes the directory at each path
in list
, by calling: Dir.rmdir(path)
; see Dir.rmdir:
FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
FileUtils.rmdir('tmp4/tmp5') # => ["tmp4/tmp5"]
Keyword arguments:
-
parents: true
- removes successive ancestor directories if empty. -
noop: true
- does not remove directories. -
verbose: true
- prints an equivalent command:FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true) FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
Output:
rmdir -p tmp0/tmp1 tmp2/tmp3 rmdir -p tmp4/tmp5
Raises an exception if a directory does not exist or if for any reason a directory cannot be removed.
Related: methods for deleting.
ln link #
FileUtils::ln
(from ruby core)
ln(src, dest, force: nil, noop: nil, verbose: nil)
Creates hard links.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths.
When src
is the path to an existing file and dest
is the path to a non-existent file, creates a hard link at dest
pointing to src
; returns zero:
Dir.children('tmp0/') # => ["t.txt"]
Dir.children('tmp1/') # => []
FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk') # => 0
Dir.children('tmp1/') # => ["t.lnk"]
When src
is the path to an existing file and dest
is the path to an existing directory, creates a hard link at dest/src
pointing to src
; returns zero:
Dir.children('tmp2') # => ["t.dat"]
Dir.children('tmp3') # => []
FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0
Dir.children('tmp3') # => ["t.dat"]
When src
is an array of paths to existing files and dest
is the path to an existing directory, then for each path target
in src
, creates a hard link at dest/target
pointing to target
; returns src
:
Dir.children('tmp4/') # => []
FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/') # => ["tmp0/t.txt", "tmp2/t.dat"]
Dir.children('tmp4/') # => ["t.dat", "t.txt"]
Keyword arguments:
-
force: true
- overwritesdest
if it exists. -
noop: true
- does not create links. -
verbose: true
- prints an equivalent command:FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true) FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true) FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/', verbose: true)
Output:
ln tmp0/t.txt tmp1/t.lnk ln tmp2/t.dat tmp3 ln tmp0/t.txt tmp2/t.dat tmp4/
Raises an exception if dest
is the path to an existing file and keyword argument force
is not true
.
FileUtils#link is an alias for FileUtils#ln.
Related: FileUtils.link_entry (has different options).
FileUtils::ln_s
(from ruby core)
ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
Creates symbolic links.
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths.
If src
is the path to an existing file:
-
When
dest
is the path to a non-existent file, creates a symbolic link atdest
pointing tosrc
:FileUtils.touch('src0.txt') File.exist?('dest0.txt') # => false FileUtils.ln_s('src0.txt', 'dest0.txt') File.symlink?('dest0.txt') # => true
-
When
dest
is the path to an existing file, creates a symbolic link atdest
pointing tosrc
if and only if keyword argumentforce: true
is given (raises an exception otherwise):FileUtils.touch('src1.txt') FileUtils.touch('dest1.txt') FileUtils.ln_s('src1.txt', 'dest1.txt', force: true) FileTest.symlink?('dest1.txt') # => true FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
If dest
is the path to a directory, creates a symbolic link at dest/src
pointing to src
:
FileUtils.touch('src2.txt')
FileUtils.mkdir('destdir2')
FileUtils.ln_s('src2.txt', 'destdir2')
File.symlink?('destdir2/src2.txt') # => true
If src
is an array of paths to existing files and dest
is a directory, for each child child
in src
creates a symbolic link dest/child
pointing to child
:
FileUtils.mkdir('srcdir3')
FileUtils.touch('srcdir3/src0.txt')
FileUtils.touch('srcdir3/src1.txt')
FileUtils.mkdir('destdir3')
FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3')
File.symlink?('destdir3/src0.txt') # => true
File.symlink?('destdir3/src1.txt') # => true
Keyword arguments:
-
force: true
- overwritesdest
if it exists. -
relative: false
- create links relative todest
. -
noop: true
- does not create links. -
verbose: true
- prints an equivalent command:FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true) FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true) FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true) FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3', noop: true, verbose: true)
Output:
ln -s src0.txt dest0.txt ln -s src1.txt destdir1 ln -sf src2.txt dest2.txt ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3
FileUtils.symlink is an alias for FileUtils.ln_s.
Related: FileUtils.ln_sf.
FileUtils::ln_sf
(from ruby core)
ln_sf(src, dest, noop: nil, verbose: nil)
Like FileUtils.ln_s, but always with keyword argument force: true
given.
FileUtils::ln_sr
(from ruby core)
ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
Like FileUtils.ln_s, but create links relative to dest
.
unlink #
File::unlink
(from ruby core)
File.delete(file_name, ...) -> integer
File.unlink(file_name, ...) -> integer
Deletes the named files, returning the number of names passed as arguments. Raises an exception on any error. Since the underlying implementation relies on the unlink(2)
system call, the type of exception raised depends on its error type (see linux.die.net/man/2/unlink) and has the form of e.g. Errno::ENOENT.
See also Dir::rmdir.
chmod #
File::chmod
(from ruby core)
File.chmod(mode_int, file_name, ... ) -> integer
Changes permission bits on the named file(s) to the bit pattern represented by mode_int. Actual effects are operating system dependent (see the beginning of this section). On Unix systems, see chmod(2)
for details. Returns the number of files processed.
File.chmod(0644, "testfile", "out") #=> 2
chown #
File::chown
(from ruby core)
File.chown(owner_int, group_int, file_name, ...) -> integer
Changes the owner and group of the named file(s) to the given numeric owner and group id’s. Only a process with superuser privileges may change the owner of a file. The current owner of a file may change the file’s group to any group to which the owner belongs. A nil
or -1 owner or group id is ignored. Returns the number of files processed.
File.chown(nil, 100, "testfile")
cmp #
FileUtils::cmp
(from ruby core)
cmp(a, b)
(This method is an alias for FileUtils#compare_file.)
Returns true
if the contents of files a
and b
are identical, false
otherwise.
Arguments a
and b
should be interpretable as a path.
FileUtils.identical? and FileUtils.cmp are aliases for FileUtils.compare_file.
Related: FileUtils.compare_stream.
install #
FileUtils::install
(from ruby core)
install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil)
Copies a file entry. See install(1).
Arguments src
(a single path or an array of paths) and dest
(a single path) should be interpretable as paths;
If the entry at dest
does not exist, copies from src
to dest
:
File.read('src0.txt') # => "aaa\n"
File.exist?('dest0.txt') # => false
FileUtils.install('src0.txt', 'dest0.txt')
File.read('dest0.txt') # => "aaa\n"
If dest
is a file entry, copies from src
to dest
, overwriting:
File.read('src1.txt') # => "aaa\n"
File.read('dest1.txt') # => "bbb\n"
FileUtils.install('src1.txt', 'dest1.txt')
File.read('dest1.txt') # => "aaa\n"
If dest
is a directory entry, copies from src
to dest/src
, overwriting if necessary:
File.read('src2.txt') # => "aaa\n"
File.read('dest2/src2.txt') # => "bbb\n"
FileUtils.install('src2.txt', 'dest2')
File.read('dest2/src2.txt') # => "aaa\n"
If src
is an array of paths and dest
points to a directory, copies each path path
in src
to dest/path
:
File.file?('src3.txt') # => true
File.file?('src3.dat') # => true
FileUtils.mkdir('dest3')
FileUtils.install(['src3.txt', 'src3.dat'], 'dest3')
File.file?('dest3/src3.txt') # => true
File.file?('dest3/src3.dat') # => true
Keyword arguments:
-
group: group
- changes the group if notnil
, using File.chown. -
mode: permissions
- changes the permissions. using File.chmod. -
noop: true
- does not copy entries; returnsnil
. -
owner: owner
- changes the owner if notnil
, using File.chown. -
preserve: true
- preserve timestamps using File.utime. -
verbose: true
- prints an equivalent command:FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true) FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true) FileUtils.install('src2.txt', 'dest2', noop: true, verbose: true)
Output:
install -c src0.txt dest0.txt install -c src1.txt dest1.txt install -c src2.txt dest2
Related: methods for copying.
truncate #
File::truncate
(from ruby core)
File.truncate(file_name, integer) -> 0
Truncates the file file_name to be at most integer bytes long. Not available on all platforms.
f = File.new("out", "w")
f.write("1234567890") #=> 10
f.close #=> nil
File.truncate("out", 5) #=> 0
File.size("out") #=> 5
chroot #
Dir::chroot
(from ruby core)
Dir.chroot( string ) -> 0
Changes this process’s idea of the file system root. Only a privileged process may make this call. Not available on all platforms. On Unix systems, see chroot(2)
for more information.
file #
Equivalent Ruby gem: ruby-filemagic
System Infomations
hostname #
Socket::gethostname
(from ruby core)
Socket.gethostname => hostname
Returns the hostname.
p Socket.gethostname #=> "hal"
Note that it is not guaranteed to be able to convert to IP address using gethostbyname, getaddrinfo, etc. If you need local IP address, use Socket.ip_address_list.
ps #
Equivalent Ruby gem: sys-proctable
Security Related
base64 #
Base64
(from ruby core)
The Base64 module provides for the encoding (#encode64, #strict_encode64, #urlsafe_encode64) and decoding (#decode64, #strict_decode64, #urlsafe_decode64) of binary data using a Base64 representation.
Example
A simple encoding and decoding.
require "base64"
enc = Base64.encode64('Send reinforcements')
# -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
plain = Base64.decode64(enc)
# -> "Send reinforcements"
The purpose of using base64 to encode data is that it translates any binary data into purely printable characters.
Instance methods:
decode64
encode64
strict_decode64
strict_encode64
urlsafe_decode64
urlsafe_encode64
cksum #
Digest
(from ruby core)
This module provides a framework for message digest libraries.
You may want to look at OpenSSL::Digest as it supports more algorithms.
A cryptographic hash function is a procedure that takes data and returns a fixed bit string: the hash value, also known as digest. Hash functions are also called one-way functions, it is easy to compute a digest from a message, but it is infeasible to generate a message from a digest.
Examples
require 'digest'
# Compute a complete digest
Digest::SHA256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
sha256 = Digest::SHA256.new
sha256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
# Other encoding formats
Digest::SHA256.hexdigest 'message' #=> "ab530a13e459..."
Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..."
# Compute digest by chunks
md5 = Digest::MD5.new
md5.update 'message1'
md5 << 'message2' # << is an alias for update
md5.hexdigest #=> "94af09c09bb9..."
# Compute digest for a file
sha256 = Digest::SHA256.file 'testfile'
sha256.hexdigest
Additionally digests can be encoded in “bubble babble” format as a sequence of consonants and vowels which is more recognizable and comparable than a hexadecimal digest.
require 'digest/bubblebabble'
Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..."
See the bubble babble specification at web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima- 01.txt.
Digest algorithms
Different digest algorithms (or hash functions) are available:
MD5:
See RFC 1321 The MD5 Message-Digest Algorithm
RIPEMD-160:
As Digest::RMD160. See
http://homes.esat.kuleuven.be/~bosselae/ripemd160.html.
SHA1:
See FIPS 180 Secure Hash Standard.
SHA2 family:
See FIPS 180 Secure Hash Standard which defines the following
algorithms:
* SHA512
* SHA384
* SHA256
The latest versions of the FIPS publications can be found here: csrc.nist.gov/publications/PubsFIPS.html.
Constants:
REQUIRE_MUTEX:
A mutex for Digest().
VERSION:
[not documented]
Class methods:
bubblebabble
hexencode
md5sum #
Digest::MD5 < Digest::Base
(from ruby core)
A class for calculating message digests using the MD5 Message-Digest Algorithm by RSA Data Security, Inc., described in RFC1321.
MD5 calculates a digest of 128 bits (16 bytes).
Examples
require 'digest'
# Compute a complete digest
Digest::MD5.hexdigest 'abc' #=> "90015098..."
# Compute digest by chunks
md5 = Digest::MD5.new # =>#<Digest::MD5>
md5.update "ab"
md5 << "c" # alias for #update
md5.hexdigest # => "90015098..."
# Use the same object to compute another digest
md5.reset
md5 << "message"
md5.hexdigest # => "78e73102..."
sha1sum #
Digest::SHA1 < Digest::Base
(from ruby core)
A class for calculating message digests using the SHA-1 Secure Hash Algorithm by NIST (the US’ National Institute of Standards and Technology), described in FIPS PUB 180-1.
See Digest::Instance for digest API.
SHA-1 calculates a digest of 160 bits (20 bytes).
Examples
require 'digest'
# Compute a complete digest
Digest::SHA1.hexdigest 'abc' #=> "a9993e36..."
# Compute digest by chunks
sha1 = Digest::SHA1.new # =>#<Digest::SHA1>
sha1.update "ab"
sha1 << "c" # alias for #update
sha1.hexdigest # => "a9993e36..."
# Use the same object to compute another digest
sha1.reset
sha1 << "message"
sha1.hexdigest # => "6f9b9af3..."
sha224sum sha256sum sha384sum sha512sum #
Digest::SHA2 < Digest::Class
(from ruby core)
A meta digest provider class for SHA256, SHA384 and SHA512.
FIPS 180-2 describes SHA2 family of digest algorithms. It defines three algorithms:
-
one which works on chunks of 512 bits and returns a 256-bit digest (SHA256),
-
one which works on chunks of 1024 bits and returns a 384-bit digest (SHA384),
-
and one which works on chunks of 1024 bits and returns a 512-bit digest (SHA512).
Examples
require 'digest'
# Compute a complete digest
Digest::SHA2.hexdigest 'abc' # => "ba7816bf8..."
Digest::SHA2.new(256).hexdigest 'abc' # => "ba7816bf8..."
Digest::SHA256.hexdigest 'abc' # => "ba7816bf8..."
Digest::SHA2.new(384).hexdigest 'abc' # => "cb00753f4..."
Digest::SHA384.hexdigest 'abc' # => "cb00753f4..."
Digest::SHA2.new(512).hexdigest 'abc' # => "ddaf35a19..."
Digest::SHA512.hexdigest 'abc' # => "ddaf35a19..."
# Compute digest by chunks
sha2 = Digest::SHA2.new # =>#<Digest::SHA2:256>
sha2.update "ab"
sha2 << "c" # alias for #update
sha2.hexdigest # => "ba7816bf8..."
# Use the same object to compute another digest
sha2.reset
sha2 << "message"
sha2.hexdigest # => "ab530a13e..."
Class methods:
new
Instance methods:
<<
block_length
digest_length
reset
update
uuidgen #
Random::Formatter#uuid
(from ruby core)
Implementation from Formatter
uuid()
Generate a random v4 UUID (Universally Unique IDentifier).
require 'random/formatter'
Random.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
Random.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
# or
prng = Random.new
prng.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
The version 4 UUID is purely random (except the version). It doesn’t contain meaningful information such as MAC addresses, timestamps, etc.
The result contains 122 random bits (15.25 random bytes).
See RFC4122 for details of UUID.