All notes
Ruby

Quick Start

China mirror

ruby-china. Add in Gemfile:


source 'https://cache.ruby-china.org/pub/ruby'

Command line

ruby



ruby -e 'puts "Hello"'
# Hello

# -c: Causes Ruby to check the syntax of the script and exit without executing.
ruby -c test/test_helper.rb

# -p: print the value of variable $_ at each end of the loop
echo matz | ruby -p -e '$_.tr! "a-z", "A-Z"'
# MATZ

######
# -i.ext: Specifies in-place-edit mode. ".ext" added to old file name to make a backup copy.

echo matz > /tmp/junk
cat /tmp/junk
# matz

ruby -p -i.bak -e '$_.upcase!' /tmp/junk

cat /tmp/junk
# MATZ
cat /tmp/junk.bak
# matz
######

# Replaces foo with bar in all .c and .h files, backing up the original files with ".bak" appended:
ruby -i.bak -pe 'sub "foo", "bar"' *.[ch]

This program works like the UNIX cat command (but works slower than cat):

% ruby -pe 0 file

# ri: Ruby API.
ri Enumerable

# Interactive Ruby.
irb
# Passing -r to irb will automatically require a library
irb -rpp

erb


erb /path/to/a.erb

Scripts

ruby-lang.org: ruby from other languages.



# For loop.
some_list.each do |this_item|
  # Deal with this_item.
end

##########
# Everything has a value. No difference between an expression and a statement.

x = 10
y = 11
z = if x < y
      true
    else
      false
    end
z # => true
##########

# Symbols
:george.object_id == :george.object_id
# true
"george".object_id == "george".object_id
# false

# “Everything is an object” isn’t just hyperbole.
# This is the same as
# class MyClass
#   attr_accessor :instance_var
# end
MyClass = Class.new do
  attr_accessor :instance_var
end

##########
# Keyword arguments

def deliver(from: "A", to: nil, via: "mail")
  "Sending from #{from} to #{to} via #{via}."
end

deliver(to: "B")
# => "Sending from A to B via mail."
deliver(via: "Pony Express", from: "B", to: "A")
# => "Sending from B to A via Pony Express."
##########

# In Ruby, everything except nil and false is considered true.
if 0
  puts "0 is true"
else
  puts "0 is false"
end
# Prints “0 is true”.

Constants are not really constant: If you modify an already initialized constant, it will trigger a warning, but not halt your program.

Naming conventions. An identifier starting with:



Constant = 10
def Constant
  11
end
# Now Constant is 10, but Constant() is 11.

Debugger

tutorialspoint.com: ruby debugger.



ruby -r debug filename[, ...]

########## Common

b file:line
b class:method
b # Show all breaks.
del[ete] n # delete breakpoint n.

enable/disable breakpoints

c
s/n [n]

w[here] # Displays stack frame
f[rame] # Same as w.
up/down [ n] # Moves up/down n levels in the stack frame

fin[ish] # Finishes execution of the current method

l[ist][<-| n- m>]
# l= # Go to current line.

# Displays variables:
v[ar] g[lobal]
v[ar] l[ocal]
v[ar] i[instance] object # Displays instance variables of object
v[ar] c[onst] object # Displays constants of object

##########

disp[lay] expression
undisp n # Remove display of n.

p expression # Evaluates the expression

wat[ch] expression
cat[ch] exception/off

m[ethod] i[instance] object # Displays instance methods of object
m[ethod] class| module # Displays instance methods of the class or module

th[read] l[ist] # Displays threads
th[read] c[ur[rent]] # Displays current thread
th[read] n # Stops specified thread
th[read] stop > # Synonym for th[read] n
th[read] c[ur[rent]] n> # Synonym for th[read] n
th[read] resume > # Resumes thread n

h[elp]

Good examples


# Print the class and its methods
p anObj.class
p anObj.methods
p anObj.methods.grep(/method1/)

p anArray.length

Language reference

Literals

q, w, x, r, s

wordpress.com: q w x r s.



##### Q, q

# Q: an alternative for double-quoted strings.
%Q(Joe said: "Frank said: "#{what_frank_said}"")
# "Joe said: "Frank said: "Hello!"""

# The parenthesis “(…)” can be replaced with any other non-alphanumeric characters and non-printing characters (pairs), so the following commands are equivalent:
%Q!Joe said: "Frank said: "#{what_frank_said}""!
%Q[Joe said: "Frank said: "#{what_frank_said}""]
%Q+Joe said: "Frank said: "#{what_frank_said}""+
%/Joe said: "Frank said: "#{what_frank_said}""/

# q is like single-quoted.
%q(Joe said: 'Frank said: '#{what_frank_said} ' ')
# "Joe said: 'Frank said: '\#{what_frank_said} ' '"

##### W, w

# W: double-quoted array elements.
%W(#{foo} Bar Bar\ with\ space)
# ["Foo", "Bar", "Bar with space"]
 
# w: single-quoted array elements.
%w(#{foo} Bar Bar\ with\ space)
# ["\#{foo}", "Bar", "Bar with space"]

# wcfNote: separator is space, not comma!
# If we add commas, we will get what we don't want:
%w[info, alert, err, warning, notice, crit, debug, warn]
# => ["info,", "alert,", "err,", "warning,", "notice,", "crit,", "debug,", "warn"]

##### Others

# x: subshell command.
%x(echo foo:#{foo})
# "foo:Foo\n"

# r: Regular expressions.
%r(/home/#{foo})
# "/\\/home\\/Foo/"

# s: symbols.
%s(foo)
# :foo
%s(foo bar)
# :"foo bar"
%s(#{foo} bar)
# :"\#{foo} bar"

For complete reference, see wikibooks: ruby Literals.

Statements

require, include, load

prograils.com: load vs require, include vs extend.

`require` reads and parses files only once, when they were referenced for the first time.
`load` reads and parses files every time you call `load`.

`include` adds module’s methods as instance methods.
`extend` allows you to add them as class methods.

So when to use load? In most cases you’ll use require, but there are some cases when load is useful, for example, when your module changes frequently you may want to pick up those changes in classes that loads this module.

The require and load are 'file-level' methods used to "read" and parse files, whereas include and extend are 'language-level' methods that can extend your class with other modules.


module TestModule
  def some_method
    "Some method of #{self.class}"
  end
end

class TestIncludeClass
  include TestModule
end

# Used as instance function.
test = TestIncludeClass.new.some_method
puts test # "Some method of TestIncludeClass"

class TestExtendClass
  extend TestModule
end

# Used as class function.
test = TestExtendClass.some_method
puts test # "Some method of TestExtendClass"

SO: what is the difference between include and require.

switch, case

SO: switch in Ruby.

The comparison is done by comparing the object in the when-clause with the object in the case-clause using the === operator. That is, it does 1..5 === a and String === a, not a === 1..5. This allows for the sophisticated semantics you see above, where you can use ranges and classes and all sorts of things rather than just testing for equality.



puts case a
when 1..5
  "It's between 1 and 5"
when 6
  "It's 6"
when String
  "You passed a string"
else
  "You gave me #{a} -- I have no idea what to do with that."
end

Variables

tutorialsPoint.

Global variables

Global variables begin with "$". Local variables begin with a lowercase letter or _.



$global_variable = 10
class Class1
   def print_global
      puts "Global variable in Class1 is #$global_variable"
   end
end

Constants

In Ruby, variables starting with capitals in name are all constants.


module MixinA
  def printf
    p self.class::IamConstant
  end
end

class Hello
include MixinA
IamConstant = "Hello"
end

Hello.new.printf
# "Hello"

Operators

==, ===, eql?, equal?

SO: what's the difference between equals.

== — generic "equality"

This is the most common comparison, and thus the most fundamental place where you (as the author of a class) get to decide if two objects are "equal" or not.

=== — case equality

Ruby uses === in case/when constructs/blocks.
For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.

eql? — Hash equality

The eql? method returns true if obj and other refer to the same hash key. This is used by Hash to test members for equality. For objects of class Object, eql? is synonymous with ==. Subclasses normally continue this tradition by aliasing eql? to their overridden == method, but there are exceptions. Numeric types, for example, perform type conversion across ==, but not across eql?, so:
1 == 1.0     #=> true
1.eql? 1.0   #=> false

equal? — identity comparison

Unlike ==, the equal? method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b) iff a is the same object as b).


########## Ruby uses === in case/when constructs/blocks.
case foo
  when bar;  p 'do something'
end
# Equivalent:
if bar === foo
  p 'do something'
end

obj = obj2 = 'a'
obj.equal? obj2       # => true
obj.equal? obj.dup    # => false

Backticks, system, exec: calling shell cmd from ruby

SO: calling shell commands from ruby.



# Kernel#`. Backticks.
value = `echo 'hi'` # Returns the result of the shell command.

# Built-in syntax.
value = %x( echo 'hi' ) # Returns in same way as backticks.

# Kernel#system
wasGood = system( "echo 'hi'" ) # Returns true if the command was found and ran successfully.

# Kernel#exec
# Returns none. The current process is replaced and never continues.
exec( "echo 'hi'" )

# $? is the same as $CHILD_STATUS.
$?.pid
$?.exitstatus

Double left angle brackets

SO.



# String concatenation
"a" << "b"
# Writing output to an IO
io << "A line of text\n"
# Writing data to a message digest, HMAC or cipher
sha << "Text to be hashed"
# left-shifting of an OpenSSL::BN
bn << 2

a = ["orange"]
a << "apple"
puts a
#  ["orange", "apple"] 

## HereDoc
here_doc = <<_EOS_
# <<-: will ignore any leading or trailing whitespace.
# here_doc = <<-_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_

Single bar | and Double bar ||

SO: single pipe.


# To have another method that should be called only if any of those methods returns true, it is useful to use |
result_action if action1 | action2
# If you use logical || instead then if action1 returns true, action2 will not be called (result_action will be invoked though)

||=

rubyinside.com: ruby double pipe.

A common misconception is that a ||= b is equivalent to a = a || b, but it behaves like a || a = b
In a = a || b, a is set to something by the statement on every run, whereas with a || a = b, a is only set if a is logically false (i.e. if it's nil or false).

Ampersand



# The & calls to_proc on the object.
# http://stackoverflow.com/questions/1961030/ruby-ampersand-colon-shortcut

some_objects.each(&:foo)
# It's the same as
some_objects.each { |obj| obj.foo }

lambda



lambda {|param| puts param }
# becomes
-> (param) { puts params }

Block, proc, lambda

culttt.com: what are lambdas in ruby.



lambda = lambda {}
# Alternatively you can use this syntax:
lambda = ->() {}
lamba.class
# => Proc

##### Difference: argument handling

lambda = -> (name) { puts "Hello #{name}" }
proc = Proc.new { |name| puts "Hello #{name}" }

lambda.call("Philip")
# => Hello Philip
proc.call("Philip")
# => Hello Philip
lambda.call()
# => ArgumentError: wrong number of arguments (0 for 1)
proc.call()
# => Hello

##### Difference: return

def lambda_method
  -> () { return "I was called from inside the lambda"}.call
  return "I was called from after the lambda"
end
puts lambda_method
# => "I was called from after the lambda"

def proc_method
  Proc.new { return "I was called from inside the proc"}.call
  return "I was called from after the proc"
end
puts proc_method
# => "I was called from inside the proc"

# wcfNote: because Proc is a block, while Lambda is a function!

awaxman11.github.io.

They are all like functions being delayed to execute.



###### Block Examples

[1,2,3].each { |x| puts x*2 }   # block is in between the curly braces

[1,2,3].each do |x|
  puts x*2                    # block is everything between the do and end
end

###### Proc Examples             
p = Proc.new { |x| puts x*2 }
[1,2,3].each(&p)              # The '&' tells ruby to turn the proc into a block 

proc = Proc.new { puts "Hello World" }
proc.call                     # The body of the Proc object gets executed when called

###### Lambda Examples            
lam = lambda { |x| puts x*2 }
[1,2,3].each(&lam)

lam = lambda { puts "Hello World" }
lam.call

Lambdas and procs treat the ‘return’ keyword differently:



def lambda_test
  lam = lambda { return }
  lam.call
  puts "Hello world"
end

lambda_test                 # calling lambda_test prints 'Hello World'

# ‘return’ inside of a proc triggers the code outside of the method where the proc is being executed
def proc_test
  proc = Proc.new { return }
  proc.call
  puts "Hello world"
end

proc_test                 # calling proc_test prints nothing

next, Return value from block

SO: how to end execution of a block in ruby.



# Use next.
ClassA.expects(:method_a)
.with() { |param1, param2|
  next false unless param1.id === 1
  next false unless param2 === nil
  next true
}
.once

# NOTE: Don't use 'return' (will make caller return, where when there is no method, LocalJumpError will be raised) or 'break' (or there will be LocalJumpError: break from proc-closure). However, 'break' can be used to exit from the 'each' method.

#---------- Break out from each.
# https://stackoverflow.com/questions/8502397/ruby-syntax-break-out-from-each-do-block
# You can break with the break keyword.
[1,2,3].each do |i|
  puts i
  break
end
# will output 1. Or if you want to directly return the value, use return.

##### A good example on: next, break, return
# https://stackoverflow.com/questions/2325471/using-return-in-a-ruby-block

def thing(*args, &block)
  value = block.call
  puts "value=#{value}"
end

thing {
  return 6 * 7
}
# wcfNote: there is no way to return since it is in the outmost context of irb.
# LocalJumpError: unexpected return
#         from (irb):7:in `block in irb_binding'
#         from (irb):2:in `call'
#         from (irb):2:in `thing'

thing { break 6 * 7 }
# => 42

thing { next 6 * 7 }
# value=42
# => nil

Functions

method_missing?, respond_to_missing?

blog.marc-andre.ca.



class StereoPlayer
  def method_missing(method, *args, &block)
    if method.to_s =~ /play_(\w+)/
      puts "Here's #{$1}"
    else
      super
    end
  end

  def respond_to_missing?(method, *)
    method =~ /play_(\w+)/ || super
  end
end

p = StereoPlayer.new
p.play_some_Beethoven # => "Here's some_Beethoven"
p.respond_to? :play_some_Beethoven # => true
m = p.method(:play_some_Beethoven) # => #<Method: StereoPlayer#play_some_Beethoven>
# m acts like any other method:
m.call # => "Here's some_Beethoven"
m == p.method(:play_some_Beethoven) # => true
m.name # => :play_some_Beethoven
StereoPlayer.send :define_method, :ludwig, m
p.ludwig # => "Here's some_Beethoven"

Regexp

ruby-doc.

=~

"=~" is Ruby's basic pattern-matching operator. This operator is equivalently defined by Regexp and String so the order of String and Regexp do not matter. If a match is found, the operator returns index of first match in string, otherwise it returns nil.



"hehe" if "/" =~ %r{^/1$}
# nil
"hehe" if "/" =~ %r{^/$}
# "hehe"

/hay/ =~ 'haystack'   #=> 0
/hiy/ =~ 'haystack'   #=> nil

#---------- Regexp.last_match

# https://apidock.com/ruby/Regexp/last_match/class

/c(.)t/ =~ 'cat'        #=> 0
Regexp.last_match       #=> #<MatchData "cat" 1:"a">
Regexp.last_match(0)    #=> "cat"
Regexp.last_match(1)    #=> "a". Usually we need this one.
Regexp.last_match(2)    #=> nil

/(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/ =~ "var = val"
Regexp.last_match       #=> #<MatchData "var = val" lhs:"var" rhs:"val">
Regexp.last_match(:lhs) #=> "var"
Regexp.last_match(:rhs) #=> "val"


/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
dollars #=> "3"

/(?<vowel>[aeiou]).\k<vowel>.\k<vowel>/.match('ototomy')
#=> #<MatchData "ototo" vowel:"o">

Datatypes

String

General



# http://stackoverflow.com/questions/8616360/how-to-check-if-a-variable-is-a-number-or-a-string
1.class #=> Fixnum
"foo".class #=> String
1.is_a? Numeric #=> true
"foo".is_a? String #=> true

"    hello    ".strip   #=> "hello"
"\tgoodbye\r\n".strip   #=> "goodbye"
a="  a  "
a.strip #=> "a"
a #=> "  a  "
a.strip! #=> "a"
a #=> "a"

# String interpolation
name = "Ada"
puts "Hello, #{name}!"

To/from symbol


# String - Symbols.
# http://www.reactive.io/tips/2009/01/11/the-difference-between-ruby-symbols-and-strings
:"hello world".to_s # => "hello world"
"hello world".to_sym # => :"hello world"
"hello world".intern # => :"hello world"
# Convert to String if Symbol.
table_name = table_name.to_s if table_name.is_a? Symbol

# to_sym vs intern
# https://www.codecademy.com/en/forum_questions/512a675cf116c52d0d00674b
# They are two names for the same method, Ruby way to write expressive code.
# .to_sym tells you that a string is being converted to a symbol
# .intern, while performing precisely the same task, stresses the fact that it gets you the "internal representation" of the string – because Ruby converts all the string literals that you use in the code to symbols internally.

EOT, EOS

EOS means End Of String.

wordpress.com: ruby multiline string definition.



a_multiline_string = %Q{ 
  The city is #{city}. 
  The temp is #{5.0/9.0 * (temp_f - 32)} C 
}
# Output
" \n  The city is Butwal. \n  The temp is 40.55555555555556 C \n"

multiline_string = <<-EOS
This is the first line
My name is #{name}.
My city is #{city} city.
EOS
 => "This is the first line\nMy name is Shiva.\nMy city is Butwal city.\n"

##### with or without dash

<<EOF
My first line without dash
        EOF
EOF
# "My first line without dash\n        EOF\n" 

<<-EOF
My first line with dash. This even supports spaces before the ending delimiter.
   EOF
# "My first line with dash. This even supports spaces before the ending delimiter.\n"

Array



['Cat', 'Dog', 'Bird'].include? 'Dog'
# true

# Alternative:
%w(Cat Dog Bird).include? 'Dog'

#---- push, append
a = [ "a", "b", "c" ]
a.push("d", "e", "f")
#=> ["a", "b", "c", "d", "e", "f"]

#---- insert
# Index starts from 0. '-1' denotes the end position.
a = %w{ a b c d }
a.insert(2, 99)         #=> ["a", "b", 99, "c", "d"]
a.insert(-2, 1, 2, 3)   #=> ["a", "b", 99, "c", 1, 2, 3, "d"]

#---- unshift
a = [ "b", "c", "d" ]
a.unshift("a")   #=> ["a", "b", "c", "d"]
a.unshift(1, 2)  #=> [ 1, 2, "a", "b", "c", "d"]

# Good for $LOAD_PATH, ensuring that the file you're including is going to be first.
vendor = File.join(File.dirname(__FILE__), 'vendor')
$LOAD_PATH.unshift File.expand_path(File.join(vendor, 'ultraviolet-0.10.5',  'lib'))

#---- each, each_index

a = [ "a", "b", "c" ]
a.each_index {|x| print x, " -- " }
# 0 -- 1 -- 2 --  => ["a", "b", "c"]
a.each_with_index {|a,x| print a,":",x, " -- " }
# a:0 -- b:1 -- c:2 --  => ["a", "b", "c"]

#---- collect, map
# use collect/map instead of each to get the processed result.

a = [ "a", "b", "c", "d" ]
a.collect { |x| x + "!" }      #=> ["a!", "b!", "c!", "d!"]
a.collect do |x| x + "!" end      #=> ["a!", "b!", "c!", "d!"]

a = [ "a", "b", "c", "d" ]
a.map! {|x| x + "!" }
a #=>  [ "a!", "b!", "c!", "d!" ]
a.collect!.with_index {|x, i| x[0...i] }
a #=>  ["", "b", "c!", "d!"]

#---- product
b=%w[projA projB] # => ["projA", "projB"]
a=%W[info notice warn err crit]
b.product(a)
# => [["projA", "info"], ["projA", "notice"], ["projA", "warn"], ["projA", "err"], ["projA", "crit"], ["projB", "info"], ["projB", "notice"], ["projB", "warn"], ["projB", "err"], ["projB", "crit"]]
b.product(a).collect do |x| "#{x[0]}.#{x[1]}" end
# => ["projA.info", "projA.notice", "projA.warn", "projA.err", "projA.crit", "projB.info", "projB.notice", "projB.warn", "projB.err", "projB.crit"]

Hash

ruby-lang docs: Hash.



#---- Creation.

grades = { "Jane Doe" => 10, "Jim Doe" => 6 }

# When your keys are always symbols:
options = { :font_size => 10, :font_family => "Arial" }
# You could write it as:
options = { font_size: 10, font_family: "Arial" }

options[:font_size]  # => 10

grades = Hash.new
grades["Dorothy Doe"] = 9

# Hashes have a default value that is returned when accessing keys that do not exist in the hash.
grades = Hash.new(0)
# Or by using the default= method:
grades = {"Timmy Doe" => 8}
grades.default = 0

#---- insert, append

# https://stackoverflow.com/questions/19756139/append-key-value-pair-to-hash-with-in-ruby
# Since hashes aren't inherently ordered, there isn't a notion of appending. Ruby hashes since 1.9 maintain insertion order, however.

# Ways to add new key/value pairs:
h[:key] = "bar"
# If you want a method, use store:
h.store(:key, "bar")

# You can only use a "shovel" operator (<<) when the key exists. It is actually appending to the value of the hash as an array.
a={}
a[:ha]<<"haha"
# NoMethodError: undefined method `<<' for nil:NilClass
a[:ha]='hehe'
# => "hehe"
a[:ha]<<"haha"
# => "hehehaha"

#---- merge

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
h1.merge(h2){|key, oldval, newval| newval - oldval}
               #=> {"a"=>100, "b"=>54,  "c"=>300}
h1             #=> {"a"=>100, "b"=>200}

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
h1 #=> {"a"=>100, "b"=>254, "c"=>300}

#---- each

h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }

#---- sort, sort_by

# http://www.rubyinside.com/how-to/ruby-sort-hash
people = {
  :fred => 23,
  :joan => 18,
  :pete => 54
}
people.values.sort    # => [18, 23, 54]
people.sort   # NoMethodError: undefined method `< =>' for :joan:Symbol
people.sort_by { |name, age| age } # Note: the result becomes an array!
# => [[:joan, 18], [:fred, 23], [:pete, 54]]

set

Operations

Map



(1..4).collect {|i| i*i }   #=> [1, 4, 9, 16]
(1..4).collect { "cat"  }   #=> ["cat", "cat", "cat", "cat"]

[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]

names = ['danil', 'edmund']
names.map! {|name| name.capitalize } # now names contains ['Danil', 'Edmund']
# wcfNote: 'map' and 'collect' here are the same.
# Ruby provides an alias for programmers from the Smalltalk world to feel more at home.
# http://stackoverflow.com/questions/5254732/difference-between-map-and-collect-in-ruby

Functions

vargs, Variable Length Argument List, Asterisk Operator

wikibooks.org: variable length argument list. SO: star in ruby.



#####
# Also called the 'splat' operator. More parameters may be passed to the function, which are collected up and an array is created.
def calculate_value(x,y,*otherValues)
    puts otherValues
  end
calculate_value(1,2,'a','b','c')
# ['a', 'b', 'c'].

#####
# The asterisk operator may also precede an Array argument in a method call. In this case the Array will be expanded and the values passed in as if they were separated by commas.
arr = ['a','b','c']
calculate_value(*arr)
# has the same result as:
calculate_value('a','b','c')

#####
# Another technique that Ruby allows is to give a Hash when invoking a function, and that gives you best of all worlds: named parameters, and variable argument length.
def accepts_hash( *var )
  print "got: ", var.inspect # will print out what it received
end
  
accepts_hash :arg1 => 'giving arg1', :argN => 'giving argN'
# => got: {:argN=>"giving argN", :arg1=>"giving arg1"}
# The above code is equivalent to the more verbose:
accepts_hash( :arg1 => 'giving arg1', :argN => 'giving argN' )  # argument list enclosed in parens
accepts_hash( { :arg1 => 'giving arg1', :argN => 'giving argN' } ) # hash is explicitly created

##### Combination

def accepts_hash( *args )
  print "got: ", args.inspect # will print out what it received
  # options = args.last.is_a?(Hash) ? args.pop : {} # It is often used to extract options.
end

accepts_hash 'a', :b, :a=>123, :b=>'abc'
# got: ["a", :b, {:a=>123, :b=>"abc"}]

Ampersand operator

wikibooks: the ampersand.



def contrived(a, &f)
  # the block can be accessed through f
  f.call(a)
  
  # but yield also works !
  yield(a)
end

# this works
contrived(25) {|x| puts x}

# this raises ArgumentError, because &f isn't really an argument - it's only there to convert a block
contrived(25, lambda {|x| puts x})

The use of the ampersand is the other-way conversion - converting a Proc into a block, because many of Ruby’s great built-ins, and especially the iterators, expect to receive a block as an argument.



print "(t)imes or (p)lus: "
times = gets
print "number: "
number = Integer(gets)
if times =~ /^t/
    calc = lambda {|n| n*number }
else
    calc = lambda {|n| n+number }
end
puts((1..10).collect(&calc).join(", "))
# The collect method expects a block, but in this case it is very convenient to provide it with a Proc, since the Proc is constructed using knowledge gained from the user.

send

SO: send in Ruby.



class Klass
  def hello(*args)
    "Hello " + args.join(' ')
  end
end
k = Klass.new
k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"

# Those lines are equivalent:
1.send '+', 2
1.+(2)
1 + 2
# Note that send bypasses visibility checks, so that you can call private methods, too (useful for unit testing).

# If there is really no variable before send, that means that the global Object is used:
send :to_s    # "main"
send :class   # Object

nil?, empty?, blank?, present?, presence

SO.

.nil? can be used on any object and is true if the object is nil.
.empty? can be used on strings, arrays and hashes and returns true if they are empty.

Running .empty? on something that is nil will throw a NoMethodError. That is where .blank? comes in. It is implemented by Rails and will operate on any object.

Rails also provides .present?, which returns the negation of .blank?.



nil.blank? == true
false.blank? == true

[].blank? == true
{}.blank? == true
"".blank? == true

5.blank? == false
0.blank? == false

# .blank? also evaluates true on strings which are non-empty but contain only whitespace:
"  ".blank? == true
"  ".empty? == false

# blank? will return false even if all elements of an array are blank.
[ nil, '' ].blank? == false
[ nil, '' ].all? &:blank? == true

present? and presence


# https://apidock.com/rails/Object/presence

object.presence
# Equivalent to:
object.present? ? object : nil

# For example, something like
state   = params[:state]   if params[:state].present?
country = params[:country] if params[:country].present?
region  = state || country || 'US'
# Becomes
region = params[:state].presence || params[:country].presence || 'US'

# https://stackoverflow.com/questions/19637499/what-is-the-point-of-object-presence/19637602
region = params[:state].presence || 'US'
# => 'US'
region = params[:state] || 'US'
# => ''

p, puts, pp

SO: ruby method to print an array.



humans = %w( foo bar baz )
puts humans.inspect
# => ["foo", "bar", "baz"]
# Using p is actually equivalent of using puts + inspect on an object.
p humans
# => ["foo", "bar", "baz"]
# But keep in mind p is more a debugging tool, it should not be used for printing records in the normal workflow.

# pp (pretty print), but you need to require it first. pp works better with complex objects.
require 'pp'
pp %w( foo bar baz )

yield

SO: blocks and yields in Ruby.



class Person 
    def initialize( name ) 
         @name = name
    end

    def do_with_name 
        yield( @name ) 
    end
end

# It allows us to call that method and pass an arbitrary code block:
person = Person.new("Oscar")
person.do_with_name do |name|
    puts "Hey, his name is #{name}"
end
# Hey, his name is Oscar

## If the block is optional you should call it like:
yield(value) if block_given?

In Javascript terms, it's a standardized way of passing a callback to a given method.

&block

mixAndgo.com: ruby blocks.

It is a way to pass a reference to the block (instead of a local variable) to a method.



def my_method(&block)
  puts block
  block.call
  # Same as yield without arguments:
  # yield
end

my_method { puts "Hello!" }
# #<Proc:[email protected]/example.rb:6>
# Hello!

Exceptions

SO: begin, rescue, ensure.



begin
  # something which might raise an exception
rescue SomeExceptionClass => some_variable
  # code that deals with some exception
rescue SomeOtherException => some_other_variable
  # code that deals with some other exception
else
  # code that runs only if *no* exception was raised
ensure
  # ensure that this code always runs, no matter what
end

#####
# http://stackoverflow.com/questions/4800698/what-is-the-difference-between-raise-foo-and-raise-exception-newfoo

raise Exception.new("foo")

# raises a RuntimeError with the message set to "foo"
raise "foo"

# A rescue block without an argument will catch RuntimeErrors, but will NOT catch Exceptions. In order to catch the Exception you will have to do this:
begin
rescue Exception
end

Random

SO: how to generate a random string.


# Generate a random string with length of 10:
rand(36**10).to_s(36)

Variables

Global variables

ruby-doc.org: globals.


$:  Load path for scripts and binary modules by load or require.
$$  The process number of the Ruby running this script.
$*  Command line arguments given for the script sans args.

Classes

Class instance variable and method

In the example, both "initialize" and "show" are instance methods:



class Item
  def initialize(item_name)
    @item_name = item_name
  end
  
  def show
    puts "Instance method show invoked for '#{self}'"
  end  
  
  def to_s
    "Item: #{@item_name}"
  end
end

Item.new("silence").show

Class Variables and Methods

rubyMonk.com.



class Planet
  @@planets_count = 0
    
  def initialize(name)
    @name = name
    @@planets_count += 1
  end
  
  def self.planets_count
    @@planets_count
  end  
end

Planet.new("earth"); Planet.new("uranus")

p Planet.planets_count

A usage in application configuration:



class ApplicationConfiguration
  @@configuration = {}

  def self.set(property_name, value)
    @@configuration[property_name] = value
  end
  
  def self.get(property_name)
    @@configuration[property_name]
  end  
end

ApplicationConfiguration.set("name", "Demo Application")
ApplicationConfiguration.set("version", "0.1")

p ApplicationConfiguration.get("version")

Class instance variable VS class variable

SO.

"Class variables" are shared between a given class and its subclasses. "Class instance variables" belong to exactly one class; its subclasses are separate.

Why does this behavior exist? Well, everything in Ruby is an object—even classes. That means that each class has an object of the class Class (or rather, a subclass of Class) corresponding to it. (When you say class Foo, you're really declaring a constant Foo and assigning a class object to it.) And every Ruby object can have instance variables, so class objects can have instance variables, too.

The trouble is, instance variables on class objects don't really behave the way you usually want class variables to behave. You usually want a class variable defined in a superclass to be shared with its subclasses, but that's not how instance variables work—the subclass has its own class object, and that class object has its own instance variables. So they introduced separate class variables with the behavior you're more likely to want.

In other words, class instance variables are sort of an accident of Ruby's design. You probably shouldn't use them unless you specifically know they're what you're looking for.

Example

codeGram.com.

Use @var as class instance variable:



class Person  
  # @count is a CLASS INSTANCE VARIABLE exclusive to Person.
  # Only when you instantiate a Person (not a subclass of Person),
  # the count increases.
  @count = 0

  def initialize
    self.class.count += 1
  end

  def self.count
    @count
  end
  def self.count=(value)
    @count = value
  end
end

class Worker < Person  
  # @count is a CLASS INSTANCE VARIABLE exclusive to Worker.
  # Only when you instantiate a Worker, the count increases.
  @count = 0
end

8.times { Person.new }  
4.times { Worker.new }

p Person.count # => 8
p Worker.count # => 4

Use @var as instance variable:



class Person  

  def initialize
    @count = 0
    @count += 1
  end

  def count
    @count
  end
  def count=(value)
    @count = value
  end
end

class Worker < Person  
  @count = 0
end

8.times { Person.new }  
4.times { Worker.new }

p Person.new.count # => 1
p Worker.new.count # => 1

Use @@var, it will be shared between class instances and subclass intances - may be not what we want:



class Person  
  @@count = 0

  def initialize
    @@count += 1
  end

  def count
    @@count
  end
  def count=(value)
    @@count = value
  end
end

class Worker < Person  
  @@count = 0
end

8.times { Person.new }  
4.times { Worker.new }

p Person.new.count # => 13
p Worker.new.count # => 14

Methods

Instance methods

SO: what is double less than.



class << someinstance
  def foo
    "Hello."
  end
end

someinstance.foo
# "Hello."


class Thing
  def do_something
  end

  # When this class definition executes, the "self" is the class Thing. It's the same as saying "add the following methods to class Thing." That is, foo is a class method.
  class << self
    def foo
      puts "I am #{self}"
    end
  end
end

t = Thing.new
t.do_something  => does something
t.class.foo     => "I am Thing"
t.foo           => NoMethodError: undefined method `foo'

attr_reader, attr_writer, attr_accessor

SO: why use Ruby's attr_accessor.



attr_writer :age

# That gets translated into:

def age=(value)
  @age = value
end

##########

attr_reader :age

# That gets translated into:

def age
  @age
end

##########

attr_accessor :age
# Both reader and writer.

methods, public_methods, instance_methods

SO.


# Returns the list of public methods accessible with inherited methods excluded.
objA.public_methods(false)
# Lists the instance methods
objA.instance_methods(false)

# Lists the methods that the User class has that the base Object class does not have.
User.methods - Object.methods
User.methods - ActiveRecord::Base.methods

Module functions

alias_method

alias_method(new_name, old_name).

apidock.com: alias_method.


module Mod
  alias_method :orig_exit, :exit
  def exit(code=0)
    puts "Exiting with code #{code}"
    orig_exit(code)
  end
end
include Mod
exit(99)

# Exiting with code 99

NOTE: the previous would be better re-written using "super":


module Mod
  def exit(code = 0)
    puts "Exiting with code #{code}"
    super
  end
end

include Mod
exit 99

Difference with alias

blog.bigBinary.com: alias vs alias_method.

alias is a keyword and it is lexically scoped. It means it treats self as the value of self at the time the source code was read . In contrast alias_method treats self as the value determined at the run time.

EigenClasses

integralist.co.uk: eigenclass.

Three types of methods:



# 1. Instance methods

class Foo
  def speak
    puts "hello"
  end
end

foo = Foo.new
bar = Foo.new
foo.speak # => hello
bar.speak # => hello

# 2. Singleton methods

class Foo; end

foo = Foo.new
bar = Foo.new
def foo.speak
  puts "hello"
end

foo.speak # => hello
bar.speak # => NoMethodError: undefined method `speak' for #<Foo:0x007f97b60c1890>

# 3. Class methods

class Foo
  def self.speak
    puts "hello"
  end
end

foo = Foo.new
foo.speak # => NoMethodError: undefined method `speak' for #<Foo:0x007f97b3af0fa8>
Foo.speak # => hello

Another way of accessing an Eigenclass is with the following syntax:



# 1. Singleton methods

class Foo; end

foo = Foo.new

class << foo
  def speak
    puts "hello"
  end
end

foo.speak # => hello

# 2. Class methods

class Foo
  class << self
    def speak
      puts "hello"
    end
  end
end

Foo.speak # => hello

Singleton/Class methods are instance methods of the Eigenclass!



########## Fail to privatize class methods:

class Foo
  def self.bar
    p "im public"
  end

  private
  def self.baz
    p "im private"
  end
end

Foo.bar # => im public
Foo.baz # => im private

########## Work this way

# Singleton method example

class Foo; end

foo = Foo.new

class << foo
  def speak
    implementation_details
  end

  private

  def implementation_details
    puts "hello!!!"
  end
end

foo.speak # => hello!!!
foo.implementation_details # => NoMethodError: private method `implementation_details' called for #<Foo:0x007f97b43f3920>

# Class method example

class Foo
  class << self
      def speak
        implementation_details
      end

      private

      def implementation_details
        puts "hello!!!"
      end
  end
end

Foo.speak # => hello!!!
Foo.implementation_details # => NoMethodError: private method `implementation_details' called for Foo:Class

Recommended way to make Singleton/Class methods private:



class Foo
  def self.bar
    p "im public"
  end

  def self.baz
    p "im private"
  end

  private_class_method :baz
end

Foo.bar # => im public
Foo.baz # => NoMethodError: private method `baz' called for Foo:Class

Builtin Functions

Determine object type: is_a?, kind_of?, instance_of?

SO: determine types of an object in Ruby.



a="1"
a.class
    # => String
a.is_a?(String)
    # => true
a.respond_to?(:to_s)
    # => true
# wcfNote: Use respond_to to test for functionality, which is better than type checking. See below for "duck typing".

a = 1
a.class
    # => Fixnum
a.is_a?(String)
    # => false
a.respond_to?(:to_s)
    # => true

p 1.instance_of? Fixnum    #=> True
p "1".instance_of? String  #=> True
p [1,2].instance_of? Array #=> True

# https://stackoverflow.com/questions/3893278/ruby-kind-of-vs-instance-of-vs-is-a
# kind_of? and is_a? are synonymous. instance_of? is different from the other two in that it only returns true if the object is an instance of that exact class, not a subclass.

Duck typing: normally type checking is not done in Ruby, but instead objects are assessed based on their ability to respond to particular methods, commonly called "Duck typing". In other words, if it responds to the methods you want, there's no reason to be particular about the type.

IO



File.write('/path/to/file', 'Some glorious content')

Modules

module itself



module Mod
  include Math
  CONST = 1
  def meth
    #  ...
  end
end

Mod.class              #=> Module
Mod.constants          #=> [:CONST, :PI, :E]
Mod.instance_methods   #=> [:meth]
# For more module methods, go to http://ruby-doc.org/core-2.4.2/Module.html

Json

ruby doc: JSON.



require 'json'

my_hash = JSON.parse('{"hello": "goodbye"}')
puts my_hash["hello"] => "goodbye"

my_hash = {:hello => "goodbye"}
puts JSON.generate(my_hash) => "{\"hello\":\"goodbye\"}"
# Or:
puts {:hello => "goodbye"}.to_json => "{\"hello\":\"goodbye\"}"

# JSON.generate only allows objects or arrays to be converted to JSON syntax. to_json, however, accepts many Ruby classes even though it acts only as a method for serialization:
1.to_json => "1"

Rails

SO: Rails.env vs RAILS_ENV.



# File vendor/rails/railties/lib/initializer.rb, line 55
def env
  @_env ||= ActiveSupport::StringInquirer.new(RAILS_ENV)
end

# So instead of calling this:
Rails.env == "production"
# you can call this:
Rails.env.production?

Ruby-odbc

sql.h not found

It depends on "unixodbc-dev".


sudo apt-get install unixodbc-dev
gem install ruby-odbc

Time

ruby doc.



require 'time'

login_time.utc.iso8601
# "2017-07-14T10:31:39Z"

t = Time.now
t.iso8601  # => "2011-10-05T22:26:12-04:00"
t.rfc2822  # => "Wed, 05 Oct 2011 22:26:12 -0400"
t.httpdate # => "Thu, 06 Oct 2011 02:26:12 GMT"

Date.parse("2010-10-31") #=> 2010-10-31 00:00:00 -0500
# Any missing pieces of the date are inferred based on the current date. assuming the current date is "2011-10-31"
Time.parse("12:00") #=> 2011-10-31 12:00:00 -0500

Time.strptime("2000-10-31", "%Y-%m-%d") #=> 2000-10-31 00:00:00 -0500

FAQ

From Python to Ruby

ruby-lang: to ruby from python.

Similarities:

Differences. Unlike Python, in Ruby

Unexpected :

SO: unexpected colon.

syntax error, unexpected ':', expecting =>
...en-select', 'data-placeholder': 'State' }

You need to upgrade to the real Ruby 2.2.0 to use quoted symbols with the JavaScript-style trailing colon syntax:


{ 'some string': value }

It wasn't valid before Ruby 2.2 version.

In Ruby less than 2.2:



{hello: 'world'}
{:hello => 'world'}
# the "hash rocket" syntax:
{'hello' => 'world'}