Vous êtes sur la page 1sur 8

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:] Alphanumeric
[:alpha:] Uppercase or lowercase letter
[:blank:] Blank and tab
[:cntrl:] Control characters (at least 0x00?0x1f, 0x7f)
[:digit:] Digit
[:graph:] Printable character excluding space
[:lower:] Lowercase letter
[:print:] Any printable character (including space)
[:punct:] Printable character excluding space and alphanumeric
[:space:] Whitespace (same as \s)
[:upper:] Uppercase letter
[:xdigit:] Hex digit (0?9, a?f, A?F)

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

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 for numbers:


0.+ = octal
\d\.\d = float (u need the digit after the period to make sure its not a method
call)
\d = int
0x\d = hex
0b\d = 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.

Vous aimerez peut-être aussi