Ruby Programming/Syntax/Literals
Numerics
[edit | edit source]123 # Fixnum -123 # Fixnum (signed) 1_123 # Fixnum (underscore is ignored) -543 # Negative Fixnum 123_456_789_123_456_789 # Bignum 123.45 # Float 1.2e-3 # Float 123.45r # Rational, introduced in ruby 2.1 0xaabb # (Hexadecimal) Fixnum 0377 # (Octal) Fixnum -0b1010 # (Binary [negated]) Fixnum 0b001_001 # (Binary) Fixnum ?a # ASCII character code for 'a' (97) ?\C-a # Control-a (1) ?\M-a # Meta-a (225) ?\M-\C-a # Meta-Control-a (129)
Note: the meaning of "?x" notation has been changed. In ruby 1.9 this means not an ASCII numeric code but a string i.e. ?a == "a"
Strings
[edit | edit source]Examples:
"this is a string" => "this is a string" "three plus three is #{3+3}" => "three plus three is 6" foobar = "blah" "the value of foobar is #{foobar}" => "the value of foobar is blah" 'the value of foobar is #{foobar}' => "the value of foobar is \#{foobar}"
A string expression begins and ends with a double or single-quote mark. Double-quoted string expressions are subject to backslash notation and interpolation. A single-quoted string expression isn't; except for \' and \\.
Backslash Notation
[edit | edit source]Also called escape characters or escape sequences, they are used to insert special characters in a string.
Example:
"this is a\ntwo line string" "this string has \"quotes\" in it"
Escape Sequence | Meaning |
\n | newline (0x0a) |
\s | space (0x20) |
\r | carriage return (0x0d) |
\t | tab (0x09) |
\v | vertical tab (0x0b) |
\f | formfeed (0x0c) |
\b | backspace (0x08) |
\a | bell/alert (0x07) |
\e | escape (0x1b) |
\nnn | character with octal value nnn |
\xnn | character with hexadecimal value nn |
\unnnn | Unicode code point U+nnnn (Ruby 1.9 and later) |
\u{nnnnn} | Unicode code point U+nnnnn with more than four hex digits must be enclosed in curly braces |
\cx | control-x |
\C-x | control-x |
\M-x | meta-x |
\M-\C-x | meta-control-x |
\x | character x itself (for example \" is the double quote character) |
For characters with decimal values, you can do this:
"" << 197 # add decimal value 197 to a string
=> Å
or embed them thus:
"#{197.chr}"
Interpolation
[edit | edit source]Interpolation allows Ruby code to appear within a string. The result of evaluating that code is inserted into the string:
"1 + 2 = #{1 + 2}" # => "1 + 2 = 3"
#{expression}
The expression can be just about any Ruby code. Ruby is pretty smart about handling string delimiters that appear in the code and it generally does what you want it to do. The code will have the same side effects as it would outside the string, including any errors:
"the meaning of life is #{1/0}" => divided by 0 (ZeroDivisionError)
The % Notation
[edit | edit source]There is also a Perl-inspired way to quote strings: by using % (percent character) and specifying a delimiting character, for example:
%{78% of statistics are "made up" on the spot} => "78% of statistics are \"made up\" on the spot"
Any single non-alpha-numeric character can be used as the delimiter, %[including these], %?or these?, %~or even these things~. By using this notation, the usual string delimiters " and ' can appear in the string unescaped, but of course the new delimiter you've chosen does need to be escaped. However, if you use %(parentheses), %[square brackets], %{curly brackets} or %<pointy brackets> as delimiters then those same delimiters can appear unescaped in the string as long as they are in balanced pairs:
%(string (syntax) is pretty flexible) => "string (syntax) is pretty flexible"
A modifier character can appear after the %, as in %q[], %Q[], %x[] - these determine how the string is interpolated and what type of object is produced:
Modifier | Meaning |
%q[ ] | Non-interpolated String (except for \\ , \[ , and \] )
|
%Q[ ] | Interpolated String (default) |
%r[ ] | Interpolated Regexp (flags can appear after the closing delimiter) |
%i[ ] | Non-interpolated Array of symbols, separated by whitespace (after Ruby 2.0) |
%I[ ] | Interpolated Array of symbols, separated by whitespace (after Ruby 2.0) |
%w[ ] | Non-interpolated Array of words, separated by whitespace |
%W[ ] | Interpolated Array of words, separated by whitespace |
%x[ ] | Interpolated shell command |
%s[ ] | Non-interpolated symbol |
Here are some more examples:
%Q{one\ntwo\n#{ 1 + 2 }} => "one\ntwo\n3" %q{one\ntwo\n#{ 1 + 2 }} => "one\\ntwo\\n#{ 1 + 2 }" %r/#{name}/i => /nemo/i %w{one two three} => ["one", "two", "three"] %i{one two three} # after Ruby 2.0 => [:one, :two, :three] %x{ruby --copyright} => "ruby - Copyright (C) 1993-2009 Yukihiro Matsumoto\n"
"Here document" notation
[edit | edit source]There is yet another way to make a string, known as a 'here document', where the delimiter itself can be any string:
string = <<END on the one ton temple bell a moon-moth, folded into sleep, sits still. END
The syntax begins with << and is followed immediately by the delimiter. To end the string, the delimiter appears alone on a line.
There is a slightly nicer way to write a here document which allows the ending delimiter to be indented by whitespace:
string = <<-FIN on the one-ton temple bell a moon-moth, folded into sleep sits still. --Taniguchi Buson, 18th century; translated by X. J. Kennedy FIN
To use non-alpha-numeric characters in the delimiter, it can be quoted:
string = <<-"." Orchid - breathing incense into butterfly's wings. --Matsuo Basho; translated by Lucien Stryk .
Here documents are interpolated, unless you use single quotes around the delimiter.
The rest of the line after the opening delimiter is not interpreted as part of the string, which means you can do this:
strings = [<<END, "short", "strings"] a long string END => ["a long string\n", "short", "strings"]
You can even "stack" multiple here documents:
string = [<<ONE, <<TWO, <<THREE] the first thing ONE the second thing TWO and the third thing THREE
=> ["the first thing\n", "the second thing\n", "and the third thing\n"]
And you can even apply methods:
s = <<END.chomp.upcase # Stripped of ending new-line and uppercased.
abc
END
=> "ABC"
Command Expansion
[edit | edit source]You can execute shell commands and run any external programs, and get the output, with backticks-quoted strings.
# Print contents of current directory, just like in console window. puts `dir` # Resolve a domain name to its IP address. domain = 'ruby-lang.org' ip = `nslookup #{domain}`.match(/\d+\.\d+\.\d+\.\d+/).to_s # => 151.101.85.178 # Download this web-page with "curl", displaying the progress, then find and print an example from it. puts `curl https://en.wikibooks.org/w/index.php?title=Ruby_Programming/Syntax/Literals`.encode('utf-8') .match(%r(<h2(?:.(?!</h2>))*Numerics.*?(?=<h2))imsu).to_s # Reducing to one section. .match(%r((?<=<pre>).*?(?=</pre>))imsu ).to_s # Reducing to an example in it.
Regular Expressions
[edit | edit source]regex_one = /chapter_\d+/i #=> /chapter_\d+/i regex_two = %r(/chapter_\d+)i #=> /\/chapter_\d+/i
Arrays
[edit | edit source]An array is a collection of objects indexed by a non-negative integer.
You can create an array object by writing Array.new
, by writing an optional
comma-separated list of values inside square brackets, or if the array will only contain string objects, a space-delimited string preceded by %w
.
array_one = Array.new array_two = [] # shorthand for Array.new array_three = ["a", "b", "c"] # array_three contains "a", "b" and "c" array_four = %w[a b c d e f g] # array_four also contains "a", "b" and "c"
array_three[0] # => "a" array_three[2] # => "c" array_four[0] # => "a" #negative indices are counted back from the end array_four[-2] # => "f" #[start, count] indexing returns an array of count objects beginning at index start array_four[1,3] # => ["b", "c", "d"] #using ranges. The end position is included with two periods but not with three array_four[0..4] # => ["a", "b", "c", "d", "e"] array_four[0...4] # => ["a", "b", "c", "d"]
The last method, using %w
, is in essence shorthand for the String
method split
when the substrings are separated by whitespace only. In the following example, the first two ways of creating an array of strings are functionally identical while the last two create very different (though both valid) arrays.
array_one = %w'apple orange pear' # => ["apple", "orange", "pear"] array_two = 'apple orange pear'.split # => ["apple", "orange", "pear"] array_one == array_two # => true
array_three = %w'dog:cat:bird' # => ["dog:cat:bird"] array_four = 'dog:cat:bird'.split(':') # => ["dog", "cat", "bird"] array_three == array_four # => false
Hashes
[edit | edit source]Hashes are basically the same as arrays, except that a hash not only contains values,
but also keys pointing to those values. Each key can occur only once in a hash. A hash object
is created by writing Hash.new
or by writing an optional list of comma-separated
key => value
pairs inside curly braces.
hash_one = Hash.new hash_two = {} # shorthand for Hash.new hash_three = {"a" => 1, "b" => 2, "c" => 3} #=> {"a"=>1, "b"=>2, "c"=>3}
Usually Symbols are used for Hash keys (allows for quicker access), so you will see hashes declared like this:
hash_sym = { :a => 1, :b => 2, :c => 3} #=> {:b=>2, :c=>3, :a=>1} hash_sym = { a: 1, b: 2, c: 3} #=> {:b=>2, :c=>3, :a=>1}
The latter form was introduced in Ruby 1.9.
Hash ordering
[edit | edit source]Note that with 1.8, iterating over hashes will iterate over the key value pairs in a "random" order. Beginning with 1.9, it will iterate over them in the order they were inserted. Note however, that if you reinsert a key without first deleting it, or change an existing key's value, the key's order in iteration does not change.
>> a = {:a => 1, :b => 2, :c => 3} => {:a=>1, :b=>2, :c=>3} >> a.keys # iterate over, show me the keys => [:a, :b, :c] >> a[:b] = 2 > a.keys => [:a, :b, :c] # same order >> a.delete(:b) >> a[:b] = 4 # re insert now => 4 >> a.keys => [:a, :c, :b] # different order
Ranges
[edit | edit source]A range represents a subset of all possible values of a type, to be more precise, all possible values between a start value and an end value.
This may be:
- All integers between 0 and 5.
- All numbers (including non-integers) between 0 and 1, excluding 1.
- All characters between 't' and 'y'.
In Ruby, these ranges are expressed by:
0..5 0.0...1.0 't'..'y'
Therefore, ranges consist of a start value, an end value, and whether the end value is included or not (in this short syntax, using two . for including and three . for excluding).
A range represents a set of values, not a sequence. Therefore,
5..0
though syntactically correct, produces a range of length zero.
Ranges can only be formed from instances of the same class or subclasses of a common parent, which must be Comparable (implementing <=>).
Ranges are instances of the Range class, and have certain methods, for example, to determine whether a value is inside a range:
r = 0..5 puts r === 4 # => true puts r === 7 # => false
For detailed information of all Range methods, consult the Range class reference.
Here is a tutorial on their use.