Strings ------------------------"" #expansion String.

new #constructor '' #no expansion %{} #keeps formatting %q{} #keeps formatting no expansion %w{a b c} #returns an array of strings no expansion string = <<EOF #here document

Regexes ------------------------/literal/ %r{literal} Regexp.new 'pattern' #string or literal Regexp#match 'string' =~ returns an index or nil if the pattern has groups, $1, $2, etc.. can be used to reference them after a match Character classes: [:alnum:] [:alpha:] [:blank:] [:cntrl:] [:digit:] [:graph:] [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:] Alphanumeric Uppercase or lowercase letter Blank and tab Control characters (at least 0x00?0x1f, 0x7f) Digit Printable character excluding space Lowercase letter Any printable character (including space) Printable character excluding space and alphanumeric Whitespace (same as \s) Uppercase letter Hex digit (0?9, a?f, A?F) # match a time hh:mm ? ? ? ? ? ? MatchData "12:34" "12" "34" "Time: " "am"

OO regexes: re = /(\d+):(\d+)/ md = re.match("Time: 12:34am") md.class md[0] # == $& md[1] # == $1 md[2] # == $2 md.pre_match # == $` md.post_match # == $'

Inheritance and modules ------------------------Module and class names must start with a capital letter You can use modules as namespaces To call a function in a module, use Module::func or Module.func or even ::Module::func and ::Module.func (bug?) Use Object#extend to include modules programmatically Requires

------------------------'require' loads a file only once and takes the name of the file, with or without .rb, and puts the file in $" 'load' loads a file unconditionnaly and needs the .rb extension both look at $: for the specified file 'require' can load shared binary libraries local vars aren't propagated both method calls are in Kernel and can be part of the code logic load takes an extra parameter (wrap). When true, it executes the code in an anonymous module. Files and directories ------------------------File.file? checks if the arg is a real file File.exists? checks if the arg exists at all (might be a dir or a special file) You also have directory? socket? symlink? pipe? You can check permissions on a file with readable? writable? executable? Use Dir.entries and Dir.foreach to process the files in a dir You can also use Dir[expr] to grab an array of the files matching expr, where expr is about the same as the shell's rules Dir[expr] can load directory trees (** = any number of dirs) Reading files from a directory will empty the data stream. You need to call #rewind on it to get the files back Use Kernel#open('file').each {|line| puts line} #to iterate over each line (u need to close the file afterward) Use Kernel#open('file') {|file| f.readlines } #to load all the lines of the file in an array Use File#open('file', 'flags'){|f| f.puts 'asdasd'} #to write to a file quickly mode strings to use with Kernel#open or IO#open r Read-only, starts at beginning of file (default mode). r+ Read/write, starts at beginning of file. w Write-only, truncates an existing file to zero length or creates a new file for writing w+ Read/write, truncates existing file to zero length or creates a new file for reading and writing. a Write-only, starts at end of file if file exists; otherwise creates a new file for writing. a+ Read/write, starts at end of file if file exists; otherwise creates a new file for reading and writing. b (DOS/Windows only) Binary file mode (may appear with any of the key letters listed above). You can get a lock on a file using File#flock(File::LOCK_(SH|EX|NB|UN)) Use StringIO to treat a string as a file Other methods of interest: FileUtils.touch Dir.mkdir

FileUtils.remove_dir Dir.getwd Dir.chdir The 'find' library contains methods to find files in a tree Exception Handling ------------------------begin #dangerous code rescue Exception => e #dont use global vars (are they thread local?) #healing code retry #goes back to begin else #gets here if no exception occurred ensure #finally block end #Use throw and catch to get out of multiple loops or to make sure exception handling is not used to carry the logic of your program #After a catch(:sym){} ruby executes the given block and if it encounters a throw, it goes up the food chain up to the appropriate catch. #When the appropriate catch is found, execution continues after the block #the symbol is given to the block in argument catch (:done) do while line = gets throw :done unless fields = line.split(/\t/) songlist.add(Song.new(*fields)) end songlist.play end When rescuing, if you do not specify an exception class, the default is StandardError When rescuing, ruby looks for the rescue block rescuing the exception class or any of its parents if you just call raise, you're raising $! or a RuntimeError (use it to raise $! only though) raise has an alias 'fail' raise is in Kernel Reflection -----------------------ancestors #returns a list of classes and modules inherited including the class/module itself methods #all the publicly accessible methods (use on the class of an object to get class methods) undef_method #prevents the current class from responding to the method in arg (a symbol) remove_method #prevents the current class from responding to the method in arg (a symbol) but ruby will still look in the parent classes instance_methods instance_variables singleton_methods ...and a slew of other methods to get methods

Call Object#method(:method_name) to get a Method object (then Method#call to call it) Blocks and procs ----------------------using lambda (or proc) is the preferred way to create a block as the resulting block will check for correct arity when called: block = lambda {|a| puts a} This function accepts a block explicitly (they can all accept blocks implicitly and check for one using 'block_given?'): def callme(&aBlock) yield end each #yield for every object each_with_index #ditto with an extra param: the index collect #yield and puts in an array the result for every object inject #yield for every object and carries the result grep #returns an array of every element in the orig array which matches the argument (===), if a block is given, each matching element is passed to it and the result is put in the output array reject #returns an array of the items for which the block is not true Threads and processes -----------------------create a thread by calling Thread.new and give it the variables the thread needs, they are going to be local to the thread t = Thread.new ('abc'){|abc| puts abc} #for example Thread#join blocks until the receiver terminates. If given a timeout argument and timeout occurs, join returns nil. A similar method #value returns the value of the last statement You can create per-thread variables, accessible from anywhere, by treating the Thread object like a hash Thread.current["var_name"] = 'value' if the flag Thread.abort_on_exception is set to false (default), an uncaught exception in a thread will only kill the thread. The exception would bubble up if you call #join on the thread. You might wanna call print 'string\n' instead of puts in a thread as puts is prone to rescheduling mid-stream Thread#pass tells the sheduler to invoke another thread Thread#stop and Thread#run can be used, though it's bad form, to stop and run threads The monitor library can be used to synchronize critical sections a la Java The Queue class in the thread library can be used to synchronize a producer/consumer situation Use ConditionVariables to wait and signal (#new_cond on a MonitorMixin) You can also use the built-in Mutex and ConditionVariable classes

Easiest way to fork: pid = fork do puts 'im a child' exit 1 end #parent's code #$?.exitstatus contains 1 After forking a child, Process.wait will wait and return the exit code while Kernel#detach will detach You can also setup a Signal#trap {} if you dont wanna wait but care about the results The child can use Kernel#exit! to exit without running any at_exit code Scripting -----------------------$* or ARGV #contains the arguments ARGF #contains the program's input files (really ARGV as if they were files) output = %x{echo a} #runs the command in a subshell, returns output, sets $? output = `echo a` #ditto true|false = system('echo a') #runs the command in a subshell, returns true if successful, else false (single arg == shell expansion) exec('echo a') #replaces the program with the command (single arg == shell expansion) eval("puts 'a'") #evaluates the ruby expression, also takes a binding IO.popen #scripts external non-interactive programs (to use stdin of the external program) IO.popen("su -c 'echo /etc/passwd'", 'r+') do |io| #this does not work because of restrictions on su -c io.puts 'password' io.close_write #you need to close write before you read return io.read end #On Unices you can spawn a ruby process like this: IO.popen('-', 'r+') do |child_filehandle| if child_filehandle $stderr.puts "I am the parent: #{child_filehandle.inspect}" child_filehandle.puts '404' child_filehandle.close_write puts "My child says the square root of 404 is #{child_filehandle.read}" else $stderr.puts "I am the child: #{child_filehandle.inspect}" number = $stdin.readline.strip.to_i $stdout.puts Math.sqrt(number) end end # I am the child: nil # I am the parent: #<IO:0xb7d25b9c> # My child says the square root of 404 is 20.0997512422418 Open3.popen3 #only on Unices, useful to capture STDERR as well

require 'open3' Open3.popen3('ls -l no_such_directory') { |stdin, stdout, stderr| stderr.read } # => "ls: no_such_directory: No such file or directory\n" To run as a daemon process (Unices), require 'daemonize' and call Daemonize::daemonize Alternatively, the above code works and uses only the standard library: def daemonize exit!(0) if fork Process::setsid #detach from shell exit!(0) if fork Dir::chdir("/") File::umask(0) STDIN.reopen("/dev/null") STDOUT.reopen("/dev/null", "w") STDERR.reopen("/dev/null", "w") yield if block_given? end change a file's permissions with File.chmod Assign a file or a stringIO to $stdout or $stderr to redirect the streams Go back to the original by assigning back to STD(OUT|ERR) Kernel#gets(separator=$/) will grab a line from $stdin or ARGF and returns nil at EOF A neat trick is to put -e "ruby code" in a -n or -p loop. -n will assume a while gets; ...; end around the code -p will assume a while gets; ...; print; end around the code For example: ruby -p -e '$_.downcase!' *.txt Global variables -----------------------$! latest error message (thread local) $@ location of error (thread local) $_ string last read by gets (local scope) $/ input record separator (defaults to newline) $-0 synonym for $/ $\ output record separator (defaults to nil) $0 the name of the top level program __FILE__ the name of the current source file $$ interpreter's process ID $fi exit status of last executed child process $: path when looking for ruby files $-I Synonym for $:. [r/o] $LOAD_PATH A synonym for $:. [r/o] $" a list of files that have been 'required' $> destination of output for Kernel#print $; default separator to String#split $-F synonym for $; $, separator used by Kernel#print and Array#join ENV environment hash __LINE__ The current line number in the source file. [r/o] $SAFE The current safe level (see page 380). This variable's value may never be reduced by assignment. [thread] $binding only used by irb

::arguments:: $* the command line arguments ARGV synonym for $* $-a true if -a is specified on the CLI (autosplit) $DEBUG true if -d is specified on the CLI $-d synonym for $DEBUG ARGF input files array $< synonym for ARGF $FILENAME The name of the current input file. Equivalent to $<.filename [r/o] $. the number of the last line read from the current input file $F The array that receives the split input line if the -a command-line option is used. $-i If in-place edit mode is enabled (perhaps using the -i command-line option), $-i holds the extension used when creating the backup file. If you set a value into $-i, enables in-place edit mode. See page 168. $-K Sets the multibyte coding system for strings and regular expressions. Equivalent to the -K command-line option. See page 169. $-l Set to true if the -l option (which enables line-end processing) is present on the command line. See page 169. [r/o] $-p Set to true if the -p option (which puts an implicit while gets . . . end loop around your program) is present on the command line. See page 169. [r/o] $VERBOSE Set to true if the -v, --version, -W, or -w option is specified on the command line. Set to false if no option, or -W1 is given. Set to nil if -W0 was specified. Setting this option to true causes the interpreter and some library routines to report additional information. Setting to nil suppresses all warnings (including the output of Kernel.warn). $-v Synonym for $VERBOSE. $-w Synonym for $VERBOSE. ::regexes:: all read-only except $~ $& string last matched by regexp (thread local) $` part of the string b4 the match (thread local) $' part of the string after match (thread local) $~ the last regexp match, as an array of subexpressions (thread local) $n the nth subexpression in the last match (same as $~[n]) (thread local) $= case-insensitivity flag (deprecated) $+ contents of the highest numbered group matched (thread local) You can trace global vars like that: trace_var :$x, proc{puts "$x is now #{$x}"}

Notes -----------------------only nil and false are considered false in a boolean context Versions prior to 1.9 lack a character data type (compare to C, which provides type char for characters). This may cause surprises when slicing strings: "abc"[0] yields 97 (an integer, representing the ASCII code of the first character in the string); to obtain "a" use "abc"[0,1] (a substring of length 1) or "abc"[0].chr In "statement until expression", statement might never run if expression if already true

environment variable RUBYLIB can be used to store the location of ruby files to require Kernel#caller can be used to print the execution stack literals 0.+ = \d\.\d call) \d = 0x\d = 0b\d = for numbers: octal = float (u need the digit after the period to make sure its not a method int hex binary

The following environment variables can change Ruby's behavior: DLN_LIBRARY_PATH Search path for dynamically loaded modules. HOME Points to user's home directory. Used when expanding ~ in file and directory names. LOGDIR Fallback pointer to the user?s home directory if $HOME is not set. Used only by Dir.chdir. OPENSSL_CONF Specify location of OpenSSL con?guration ?le. RUBYLIB Additional search path for Ruby programs ($SAFE must be 0). RUBYLIB_PREFIX (Windows only) Mangle the RUBYLIB search path by adding this pre?x to each component. RUBYOPT Additional command-line options to Ruby; examined after real command-line options are parsed ($SAFE must be 0). RUBYPATH With -S option, search path for Ruby programs (defaults to PATH). RUBYSHELL Shell to use when spawning a process under Windows; if not set, will also check SHELL or COMSPEC. RUBY_TCL_DLL Override default name for TCL shared library or DLL. RUBY_TK_DLL Override default name for Tk shared library or DLL. Both this and RUBY_TCL_DLL must be set for either to be used. Safe levels (you can change them using the switch -T), more info on page 383: 0 No checking of the use of externally supplied (tainted) data is performed. This is Ruby?s default mode. >1 Ruby disallows the use of tainted data by potentially dangerous operations. >2 Ruby prohibits the loading of program ?les from globally writable locations. >3 All newly created objects are considered tainted. >4 Ruby effectively partitions the running program in two. Nontainted objects may not be modi?ed.