2. About Me
> 8 years of developing experience
retail, e-commerce, logistics,
fashion, multi-media, etc.
lead developer, team leader,
project manager, functional
analysts, architect.
a runner and a mountain lover
elimi
@I ndritS
3. Why Ruby
Everything is an Object
Dynamic typing
Open
Mix-ins
Functional support
Methods vs Keywords
(Meta)programming
‘Scripting’ support
LBNL: Testing
8. Classes
Code:
class Cls < Array Cls = Class.new(Array) do
def sum def sum
inject{ |sum, element| sum + element} inject{|sum, element| sum + element}
end end
end end
9. Classes
Code:
class Cls < Array Cls = Class.new(Array) do
def sum def sum
inject{ |sum, element| sum + element} inject{|sum, element| sum + element}
end end
end end
10. Classes
Code:
class Cls < Array Cls = Class.new(Array) do
def sum def sum
inject{ |sum, element| sum + element} inject{|sum, element| sum + element}
end end
end end
Classes are nothing but objects,
class names are nothing but constants.
11. Classes
Code:
class Cls < Array Cls = Class.new(Array) do
def sum def sum
inject{ |sum, element| sum + element} inject{|sum, element| sum + element}
end end
end end
! Classes are nothing but objects,
class names are nothing but constants.
13. Dynamic Typing
Code:
class CreditCard
def pay; #credit code; end
end
class Cod
def pay; #cod code; end
end
class WireTransfer
def pay; #wrt code; end
end
def process(payment)
...
payment.pay
...
end
18. Class Opening
Code:
3.times do def Cls.hi
class Cls puts “Hi Class”
puts “Hi” end
end
end
=> Hi
Hi
Hi
19. Class Opening
Code:
3.times do def Cls.hi
class Cls puts “Hi Class”
puts “Hi” end
end
end
=> Hi Cls.hi #=> Hi
Hi
Hi
20. Class Opening
Code:
def Cls.hi obj1 = Cls.new
3.times do
puts “Hi Class” obj2 = Cls.new
class Cls
puts “Hi” end
def obj1.hi
end
puts “Hi”
end
end
=> Hi Cls.hi #=> Hi
Hi
Hi
21. Class Opening
Code:
def Cls.hi obj1 = Cls.new
3.times do
puts “Hi Class” obj2 = Cls.new
class Cls
puts “Hi” end
def obj1.hi
end
puts “Hi”
end
end
=> Hi Cls.hi #=> Hi obj1.hi # => Hi
Hi
Hi
22. Class Opening
Code:
def Cls.hi obj1 = Cls.new
3.times do
puts “Hi Class” obj2 = Cls.new
class Cls
puts “Hi” end
def obj1.hi
end
puts “Hi”
end
end
=> Hi Cls.hi #=> Hi obj1.hi # => Hi
Hi obj2.hi # =>
Hi NoMethodError
24. Modules
Code:
module Mod
CONSTANT = 'Outer'
class Cls
CONSTANT = 'Inner'
end
end
25. Modules
Code:
module Mod
CONSTANT = 'Outer'
class Cls
CONSTANT = 'Inner'
end
end
Mod::CONSTANT => “Outer”
Mod::Cls::CONSTANT => “Inner”
26. Modules
Code:
module Mod
def my_method
'M#my_method()'
end
end
class Cls
include Mod
end
class Cls
extend Mod
end
27. Modules
Code:
module Mod
def my_method
'M#my_method()'
end
end
class Cls
include Mod Cls.new.my_method # =>“M#my_method()”
end
class Cls
extend Mod
end
28. Modules
Code:
module Mod
def my_method
'M#my_method()'
end
end
class Cls
include Mod Cls.new.my_method # =>“M#my_method()”
end
class Cls
extend Mod Cls.my_method # =>“M#my_method()”
end
29. Modules
Code:
module Mod
def my_method
'M#my_method()'
private instance
end method
end of Module
class Cls
include Mod Cls.new.my_method # =>“M#my_method()”
end
class Cls
extend Mod Cls.my_method # =>“M#my_method()”
end
30. Modules
Code:
module Mod
def my_method
'M#my_method()'
private instance
end method
end of Module
class Cls
include Mod Cls.new.my_method # =>“M#my_method()”
end
Object#extend
class Cls
extend Mod Cls.my_method # =>“M#my_method()”
end
39. Proc and Lambda
(& and to_proc)
Code:
[1, 2, 5].inject(0){|sum, e| sum + e} # => 8
40. Proc and Lambda
(& and to_proc)
Code:
[1, 2, 5].inject(0){|sum, e| sum + e} # => 8
[1, 2, 5].inject(0, &:+) # => 8
41. Proc and Lambda
(& and to_proc)
Code:
[1, 2, 5].inject(0){|sum, e| sum + e} # => 8
Symbol
[1, 2, 5].inject(0, &:+) # => 8
42. Proc and Lambda
(& and to_proc)
Code:
[1, 2, 5].inject(0){|sum, e| sum + e} # => 8
Symbol
[1, 2, 5].inject(0, &:+) # => 8
Class Symbol
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
end
49. Exceptions
Code: begin
...
begin fail “error”
raise “blew up” ...
rescue => ex rescue StandardError => ex
puts “I #{ex}” puts “Failed: ” + ex
end raise
else
...
ensure
# clean up
...
end
50. Exceptions
Code: begin
...
begin fail “error”
raise “blew up” ...
rescue => ex rescue StandardError => ex
puts “I #{ex}” puts “Failed: ” + ex
end raise
else
...
ensure
# clean up
tries = 0 ...
begin end
tries += 1
puts "Trying #{tries}..." raise "Didn’t work"
rescue
retry if tries < 3
puts "I give up"
end
51. Exceptions
Code: begin
...
begin fail “error”
raise “blew up” ...
rescue => ex rescue StandardError => ex
puts “I #{ex}” puts “Failed: ” + ex
end raise
else
...
ensure
Retry # clean up
tries = 0 ...
begin end
tries += 1
puts "Trying #{tries}..." raise "Didn’t work"
rescue
retry if tries < 3
puts "I give up"
end
56. (Meta)Programming
Class Macros Example
Code:
Class Customer
def name
@name
end
def name=(n)
@name = n
end
...
def age
@age
end
def age=(a)
@age = a
end
end
57. (Meta)Programming
Class Macros Example
Code:
Class Customer class Customer
def name attr_accessor :name, :surname, :age
@name end
end
def name=(n)
@name = n
end
...
def age
@age
end
def age=(a)
@age = a
end
end
58. (Meta)Programming
Class Macros Example
Code:
Class Customer class Customer
def name attr_accessor :name, :surname, :age
@name end
end
def name=(n) class Customer
@name = n def self.attr_accessor(*accessors)
end accessors.each do |accessor|
... define_method(accessor) do
instance_variable_get("@#{accessor}")
def age end
@age
end define_method("#{accessor}=") do |accessor_value|
instance_variable_set("@#{accessor}", accessor_value)
def age=(a) end
@age = a end
end end
end end
62. Expressions
Code:
song_type = if song.mp3Type == MP3::Jazz
if song.written < Date.new(1935, 1, 1)
Song::TradJazz
else
Song::Jazz
end
else
Song::Other
end
63. Infrastructure as code
Code:
package "rabbimq-server" do
action :install
end
service "rabbitmq-server" do
supports :status => true, :restart => true, :reload => true
action[:enable, :start]
end
65. Code:
describe Stack do
RSpec
before(:each) do
@stack = Stack.new
@stack.push :item
end
describe "#peek" do
it "returns the top element" do
@stack.peek.should == :item
end
it "doesn’t remove the top" do
@stack.peek
@stack.size.should == 1
end
end
describe "#pop" do
it "returns the top element" do
@stack.pop.should == :item
end
it "removes the top element" do
@stack.pop
@stack.size.should == 0
end
end
end
66. Code:
describe Stack do
RSpec
before(:each) do
@stack = Stack.new expect {
@stack.push :item User.create!(:role => "admin")
end }.to change{ User.admins.count }.by(1)
describe "#peek" do
it "returns the top element" do
@stack.peek.should == :item
end
it "doesn’t remove the top" do
@stack.peek
@stack.size.should == 1
end
end
describe "#pop" do
it "returns the top element" do
@stack.pop.should == :item
end
it "removes the top element" do
@stack.pop
@stack.size.should == 0
end
end
end
67. Code:
describe Stack do
RSpec
before(:each) do
@stack = Stack.new expect {
@stack.push :item User.create!(:role => "admin")
end }.to change{ User.admins.count }.by(1)
describe "#peek" do
it "returns the top element" do result.should be_close(5.25, 0.005)
@stack.peek.should == :item
end
it "doesn’t remove the top" do
@stack.peek
@stack.size.should == 1
end
end
describe "#pop" do
it "returns the top element" do
@stack.pop.should == :item
end
it "removes the top element" do
@stack.pop
@stack.size.should == 0
end
end
end
68. Code:
describe Stack do
RSpec
before(:each) do
@stack = Stack.new expect {
@stack.push :item User.create!(:role => "admin")
end }.to change{ User.admins.count }.by(1)
describe "#peek" do
it "returns the top element" do result.should be_close(5.25, 0.005)
@stack.peek.should == :item
end
it "doesn’t remove the top" do expect{do_something_risky}.to raise_error /too risky/
@stack.peek
@stack.size.should == 1
end
end
describe "#pop" do
it "returns the top element" do
@stack.pop.should == :item
end
it "removes the top element" do
@stack.pop
@stack.size.should == 0
end
end
end
69. Code:
describe Stack do
RSpec
before(:each) do
@stack = Stack.new expect {
@stack.push :item User.create!(:role => "admin")
end }.to change{ User.admins.count }.by(1)
describe "#peek" do
it "returns the top element" do result.should be_close(5.25, 0.005)
@stack.peek.should == :item
end
it "doesn’t remove the top" do expect{do_something_risky}.to raise_error /too risky/
@stack.peek
@stack.size.should == 1
end array.empty?.should == true <--> array.should be_empty
end
describe "#pop" do
it "returns the top element" do
@stack.pop.should == :item
end
it "removes the top element" do
@stack.pop
@stack.size.should == 0
end
end
end
70. Code:
describe Stack do
RSpec
before(:each) do
@stack = Stack.new expect {
@stack.push :item User.create!(:role => "admin")
end }.to change{ User.admins.count }.by(1)
describe "#peek" do
it "returns the top element" do result.should be_close(5.25, 0.005)
@stack.peek.should == :item
end
it "doesn’t remove the top" do expect{do_something_risky}.to raise_error /too risky/
@stack.peek
@stack.size.should == 1
end array.empty?.should == true <--> array.should be_empty
end
describe "#pop" do field.players.select{|p| p.team == home_team}
it "returns the top element" do .length.should == 9
@stack.pop.should == :item
end
it "removes the top element" do
@stack.pop
@stack.size.should == 0
end
end
end
71. Code:
describe Stack do
RSpec
before(:each) do
@stack = Stack.new expect {
@stack.push :item User.create!(:role => "admin")
end }.to change{ User.admins.count }.by(1)
describe "#peek" do
it "returns the top element" do result.should be_close(5.25, 0.005)
@stack.peek.should == :item
end
it "doesn’t remove the top" do expect{do_something_risky}.to raise_error /too risky/
@stack.peek
@stack.size.should == 1
end array.empty?.should == true <--> array.should be_empty
end
describe "#pop" do field.players.select{|p| p.team == home_team}
it "returns the top element" do .length.should == 9
@stack.pop.should == :item
end
home_team.should have(9).players_on(field)
it "removes the top element" do
@stack.pop
@stack.size.should == 0
end
end
end
72. Code:
describe Stack do
RSpec
before(:each) do
@stack = Stack.new expect {
@stack.push :item User.create!(:role => "admin")
end }.to change{ User.admins.count }.by(1)
describe "#peek" do
it "returns the top element" do result.should be_close(5.25, 0.005)
@stack.peek.should == :item
end
it "doesn’t remove the top" do expect{do_something_risky}.to raise_error /too risky/
@stack.peek
@stack.size.should == 1
end array.empty?.should == true <--> array.should be_empty
end
describe "#pop" do field.players.select{|p| p.team == home_team}
it "returns the top element" do .length.should == 9
@stack.pop.should == :item
end
home_team.should have(9).players_on(field)
it "removes the top element" do
@stack.pop a_politician.should have_at_least(3).escorts
@stack.size.should == 0
end
end
end
73. Code:
Cucumber
Feature: Google Search
In order to learn something
As an internet user
I want to search for information on Google
Scenario: Learn about Scrat
Given I am on google.com
When I search for "Scrat"
Then I should see search results about Scrat
When /^I search for ['"](.*)['"]$/ do |query|
fill_in('q', :with => query)
click_button('Google Search')
end
Then /^I should see search results about (.*)$/
do |term|
response_body.should include(term)
end
Disclaimer: I&#x2019;ll not teach Ruby.\n\nRuby follows: http://en.wikipedia.org/wiki/Principle_of_least_surprise.\n\nIn computer science the term refers to runtime resolution of what names mean and includes the concept of dynamic loading.\n\nLate binding is a computer programming mechanism in which the method being called upon an object is looked up by name at runtime. This is informally known as duck typing or name binding.\n
\n
An internal DSL, again according to Fowler, is one in which you start with some implementation language, perhaps Ruby, and you simply bend that one language into being your domain specific language. If you are using Ruby to implement your internal DSL, then anyone who writes a program in your little language is actually, and perhaps unknowingly, writing a Ruby program.\n
An internal DSL, again according to Fowler, is one in which you start with some implementation language, perhaps Ruby, and you simply bend that one language into being your domain specific language. If you are using Ruby to implement your internal DSL, then anyone who writes a program in your little language is actually, and perhaps unknowingly, writing a Ruby program.\n
Object has object_id method that return a fixnum identifier.\n\nThe methods of an object are the instance methods of its class.\n\n\nnil, true, false, self --> keyword literals\n\nUnlike in Java or other static languages, in Ruby there is no connection between an object&#x2019;s class and its instance variables. Instance variables just spring into existence when you assign them a value, so you can have objects of the same class that carry different sets of instance variables. You can think of the names and values of instance variables as keys and values in a hash. Both the keys and the values can be different for each object.\n\n\nOn the inside, an object simply contains its instance variables and a reference to its class. To be precise, it also contains a unique identifier (the one returned by Object#object_id( )) and a set of flags that mark special states such as &#x201C;tainted&#x201D; or &#x201C;frozen.&#x201D; To remove the ambiguity, you should say that my_method() is an instance method (not just &#x201C;a method&#x201D;) of MyClass, meaning that it&#x2019;s defined in MyClass, and you actually need an instance of MyClass to call it.\n\nAn object&#x2019;s instance variable live in the object itself and an object&#x2019;s methods live in the object&#x2019;s class. That&#x2019;s why objects of the same class share methods but don&#x2019;t share instance variables.\n\n \n
\n
inject { |sum, element| sum + element }\n
inject { |sum, element| sum + element }\n
inject { |sum, element| sum + element }\n
inject { |sum, element| sum + element }\n
\n
\n
\n
FixNum and Symbol are immediate values and can&#x2019;t be extended.\n
FixNum and Symbol are immediate values and can&#x2019;t be extended.\n
FixNum and Symbol are immediate values and can&#x2019;t be extended.\n
FixNum and Symbol are immediate values and can&#x2019;t be extended.\n
FixNum and Symbol are immediate values and can&#x2019;t be extended.\n
FixNum and Symbol are immediate values and can&#x2019;t be extended.\n
FixNum and Symbol are immediate values and can&#x2019;t be extended.\n
\n
Contants name convention (all upper case) \n\ninclude is a keyword...no! It is a private instance method of Module. It&#x2019;s arguments are only modules, not sublcasses (classes).\n\nObject#extend --> This method makes the instance methods of the specified module or modules into singleton methods of the receiver object. \nObject#extend() is simply a shortcut that includes a module in the receiver&#x2019;s eigenclass.\n\nIt is just a shortcut for this:\n\nclass << obj\n include Module \nend\n\n
Contants name convention (all upper case) \n\ninclude is a keyword...no! It is a private instance method of Module. It&#x2019;s arguments are only modules, not sublcasses (classes).\n\nObject#extend --> This method makes the instance methods of the specified module or modules into singleton methods of the receiver object. \nObject#extend() is simply a shortcut that includes a module in the receiver&#x2019;s eigenclass.\n\nIt is just a shortcut for this:\n\nclass << obj\n include Module \nend\n\n
Contants name convention (all upper case) \n\ninclude is a keyword...no! It is a private instance method of Module. It&#x2019;s arguments are only modules, not sublcasses (classes).\n\nObject#extend --> This method makes the instance methods of the specified module or modules into singleton methods of the receiver object. \nObject#extend() is simply a shortcut that includes a module in the receiver&#x2019;s eigenclass.\n\nIt is just a shortcut for this:\n\nclass << obj\n include Module \nend\n\n
Contants name convention (all upper case) \n\ninclude is a keyword...no! It is a private instance method of Module. It&#x2019;s arguments are only modules, not sublcasses (classes).\n\nObject#extend --> This method makes the instance methods of the specified module or modules into singleton methods of the receiver object. \nObject#extend() is simply a shortcut that includes a module in the receiver&#x2019;s eigenclass.\n\nIt is just a shortcut for this:\n\nclass << obj\n include Module \nend\n\n
Contants name convention (all upper case) \n\ninclude is a keyword...no! It is a private instance method of Module. It&#x2019;s arguments are only modules, not sublcasses (classes).\n\nObject#extend --> This method makes the instance methods of the specified module or modules into singleton methods of the receiver object. \nObject#extend() is simply a shortcut that includes a module in the receiver&#x2019;s eigenclass.\n\nIt is just a shortcut for this:\n\nclass << obj\n include Module \nend\n\n
\n
First, a block may appear only in the source adjacent to a method call; the block is written starting on the same line as the method call&#x2019;s last parameter (or the closing parenthesis of the parameter list).\nSecond, the code in the block is not executed at the time it is encountered. Instead, Ruby remembers the context in which the block appears (the local variables, the current object, and so on) and then enters the method.\n\nWhat makes blocks interesting, however, is that you can pass parameters to them and receive values from them.\nThe yield statement is like a method invocation; it is followed by zero or more expressions whose values are assigned to the block parameters.\n\n
\n
\n
\n
Instance variables are variables that belong to a particular object instance. Each object has its own object variables.\n\n4 types of variables (plus constant). Please note that Cls is constant, therefore global.\n\n
Blocks, Procs and Lambdas are closures.\n\nYou can define a block only when you call a method. Optionally, a block can have arguments, like x and y in Bill&#x2019;s example. When you call back to the block, you can provide values for its argu- ments, just like you do when you call a method. Also, like a method, a block returns the result of the last line of code it evaluates.\n\nA block captures the bindings that are around when you first define the block. \nYou can also define additional bindings inside the block, but they disappear after the block ends.\n\nThere are exactly three places where a program leaves the previous scope behind and opens a new one:\n&#x2022; Class definitions\n&#x2022; Module definitions\n &#x2022; Methods\nclass, module, and def\n\nThere is a subtle difference between class and module on one side and def on the other. The code in a class or module definition is executed immediately. Conversely, the code in a method definition is executed later, when you eventually call the method. However, as you write your program, you usually don&#x2019;t care when it changes scope&#x2014;you only care that it does.\nScope Wrap-Up\nEach Ruby scope contains a bunch of bindings, and the scopes are separated by Scope Gates (100): class, module, and def. If you want to sneak a binding or two through a Scope Gate, you can replace the Scope Gate with a method call: you capture the current bindings in a closure and pass the closure to the method. You can replace class with Class.new( ), module with Module.new, and def with Module#define_method( ). This is a\nSpell: Shared Scope\n\n\n\nINSTANCE_EVAL() 105\nFlat Scope (103), the basic closure-related spell. If you define multiple methods in the same Flat Scope, maybe protected by a Scope Gate, all those methods can share bindings. That&#x2019;s called a Shared Scope (104).\n\n
A block is like an additional, anonymous argument to a method.\n\nProcs have block-like behavior and lambdas have method-like behavior. Both, however, are instances of class Proc.\n\nIn most cases, you execute the block right there in the method, using yield. There are two cases where yield is not enough:\n&#x2022; You want to pass the block to another method.\n&#x2022; You want to convert the block to a Proc.\nProc vs Lambdas --> Return and Arity check\nHowever, if the last parameter in a method definition is prefixed with an ampersand, any associated block is converted to a Proc object, and that object is assigned to the parameter.\nclass Symbol\n def to_proc\n proc { |obj, *args| obj.send(self, *args) }\n end\nend\n\nTalk about coercion protocols.\n\nA Method object is similar to a lambda, with an important difference: a lambda is evaluated in the scope it&#x2019;s defined in (it&#x2019;s a closure, remember?), while a Method is evaluated in the scope of its object.\nWhen you redefine a method you don&#x2019;t really change the method. Instead you define a new method and attach an existing name to that new method.\n\nCallable Objects Wrap-Up\nCallable objects are snippets of code that you can evaluate, and they carry their own scope along with them. They can be the following:\n&#x2022; Blocks (they aren&#x2019;t really &#x201C;objects,&#x201D; but they are still &#x201C;callable&#x201D;): Evaluated in the scope in which they&#x2019;re defined.\n&#x2022; Procs: Objects of class Proc. Like blocks, they are evaluated in the scope where they&#x2019;re defined.\n&#x2022; Lambdas: Also objects of class Proc but subtly different from reg- ular procs. They&#x2019;re closures like blocks and procs, and as such they&#x2019;re evaluated in the scope where they&#x2019;re defined.\n&#x2022; Methods: Bound to an object, they are evaluated in that object&#x2019;s scope. They can also be unbound from their scope and rebound to the scope of another object.\nDifferent callable objects exhibit subtly different behaviors. In methods and lambdas, return returns from the callable object, while in procs and blocks, return returns from the callable object&#x2019;s original context. Different callable objects also react differently to calls with the wrong arity. Methods are stricter, lambdas are almost as strict (save for some corner cases), and procs and blocks are more tolerant.\nThese differences notwithstanding, you can still convert from one call- able object to another, such as by using Proc.new(), Method#to_proc(), or the & operator.\n\n\n\n\n
\n
\n
\n
\n
Public, Private, Protected are instance methods of Module class.\n\nPublic as default except: \n - methods outside of class def are private instance methods of Object. \n - initialize is implicitly private. \n\nPrivate\n - called within class or its subclasses. called in functional style m\n\nProtected\n - same as private --> within class or subclasses\n - no condition on implicit object\n\nMethods: pass by value.\nsymbol --> :&#x2018;string&#x2019; and FixNum are immediate values (immutable)\nThe existance of the immediate values should be considered an implementation detail. The immediate values could not have singleton values defined on them; different from reference values.\n\nMethod &#x2018;send&#x2019; helps in testing private methods, mention the Sandi Matz problem with testing private methods.\n\nNote that you can have different visibilities for different aliases. It&#x2019;s the method name, not the method itself, that is either public or private. See Around Aliases.\n
Public, Private, Protected are instance methods of Module class.\n\nPublic as default except: \n - methods outside of class def are private instance methods of Object. \n - initialize is implicitly private. \n\nPrivate\n - called within class or its subclasses. called in functional style m\n\nProtected\n - same as private --> within class or subclasses\n - no condition on implicit object\n\nMethods: pass by value.\nsymbol --> :&#x2018;string&#x2019; and FixNum are immediate values (immutable)\nThe existance of the immediate values should be considered an implementation detail. The immediate values could not have singleton values defined on them; different from reference values.\n\nMethod &#x2018;send&#x2019; helps in testing private methods, mention the Sandi Matz problem with testing private methods.\n\nNote that you can have different visibilities for different aliases. It&#x2019;s the method name, not the method itself, that is either public or private. See Around Aliases.\n
Public, Private, Protected are instance methods of Module class.\n\nPublic as default except: \n - methods outside of class def are private instance methods of Object. \n - initialize is implicitly private. \n\nPrivate\n - called within class or its subclasses. called in functional style m\n\nProtected\n - same as private --> within class or subclasses\n - no condition on implicit object\n\nMethods: pass by value.\nsymbol --> :&#x2018;string&#x2019; and FixNum are immediate values (immutable)\nThe existance of the immediate values should be considered an implementation detail. The immediate values could not have singleton values defined on them; different from reference values.\n\nMethod &#x2018;send&#x2019; helps in testing private methods, mention the Sandi Matz problem with testing private methods.\n\nNote that you can have different visibilities for different aliases. It&#x2019;s the method name, not the method itself, that is either public or private. See Around Aliases.\n
The rescue clauses in Ruby behave like a case statement.\n\nraise is a method.\n\nraise() equivalent of raise $! or raise RuntimeError if $!is nil.\n\nIn Ruby exception behaves like strings --> &#x201C;Failed&#x201D;+ex call ex.to_str\nException#exception behaves like an explicit coercion method like to_s or to_a. \n\nraise via aliasing becomes fail. Aliasing permits, other then advices,to correctly name the same methods between different abstraction levels. \n
The rescue clauses in Ruby behave like a case statement.\n\nraise is a method.\n\nraise() equivalent of raise $! or raise RuntimeError if $!is nil.\n\nIn Ruby exception behaves like strings --> &#x201C;Failed&#x201D;+ex call ex.to_str\nException#exception behaves like an explicit coercion method like to_s or to_a. \n\nraise via aliasing becomes fail. Aliasing permits, other then advices,to correctly name the same methods between different abstraction levels. \n
The rescue clauses in Ruby behave like a case statement.\n\nraise is a method.\n\nraise() equivalent of raise $! or raise RuntimeError if $!is nil.\n\nIn Ruby exception behaves like strings --> &#x201C;Failed&#x201D;+ex call ex.to_str\nException#exception behaves like an explicit coercion method like to_s or to_a. \n\nraise via aliasing becomes fail. Aliasing permits, other then advices,to correctly name the same methods between different abstraction levels. \n
\n
\n
\n
Metaprogramming: writing code that writes code!\nRuby is a reflective language.\n\nThe language in which the metaprogram is written is called the metalanguage. The language of the programs that are manipulated is called the object language. The ability of a programming language to be its own metalanguage is called reflection or reflexivity.\n
Metaprogramming: writing code that writes code!\nRuby is a reflective language.\n\nThe language in which the metaprogram is written is called the metalanguage. The language of the programs that are manipulated is called the object language. The ability of a programming language to be its own metalanguage is called reflection or reflexivity.\n
a.k.a. --> also known as\n
example = OpenStruct.new\nexample.empty = true\nBuilders.\n
\n
Many programming languages distinguish between low-leve expressions and higher-level statements, such as conditionals and loop. In these languages, statements control the\nflow but they do not have values. They are executed rather the evaluated.\nIn Ruby there is no clear distinction between statements and expressions; everything in Ruby, including class and method definitions, can be evaluated as an expresion and will return a value.\nOne of the first differences with Ruby is that anything that can reasonably return a value does: just about everything is an expression.\n\nFor example, the if and case statements both return the value of the last expression executed.\n\n\n\n
Continuous Integration.\n\nChecf has a client-server architecture.\n
\n
Predicate matchers (be, be_a, etc): a ruby predicate method is one whose name ends with &#x201C;?&#x201D; and returns a Boolean value. home_team.should have(9).players_on(field)\n
Predicate matchers (be, be_a, etc): a ruby predicate method is one whose name ends with &#x201C;?&#x201D; and returns a Boolean value. home_team.should have(9).players_on(field)\n
Predicate matchers (be, be_a, etc): a ruby predicate method is one whose name ends with &#x201C;?&#x201D; and returns a Boolean value. home_team.should have(9).players_on(field)\n
Predicate matchers (be, be_a, etc): a ruby predicate method is one whose name ends with &#x201C;?&#x201D; and returns a Boolean value. home_team.should have(9).players_on(field)\n
Predicate matchers (be, be_a, etc): a ruby predicate method is one whose name ends with &#x201C;?&#x201D; and returns a Boolean value. home_team.should have(9).players_on(field)\n
Predicate matchers (be, be_a, etc): a ruby predicate method is one whose name ends with &#x201C;?&#x201D; and returns a Boolean value. home_team.should have(9).players_on(field)\n
Predicate matchers (be, be_a, etc): a ruby predicate method is one whose name ends with &#x201C;?&#x201D; and returns a Boolean value. home_team.should have(9).players_on(field)\n
Cucumber is an interpreter.The Cucumber executable interprets Gherkin code in .feature files.\nLike Python and YAML, Gherkin is a line-oriented language that uses indentation to define structure.\nCucumber scenarios consist of steps, also known as Givens, Whens and Thens.\n\nThe Given/When/Then convention is central to the notion of BDD. It connects the human concept of cause and effect, to the software concept of input/process/output.\n\n
The superclass of the eigenclass is the eigenclass of the superclass. It&#x2019;s easy!\n
Around Aliases: Note that you can have different visibilities for different aliases. It&#x2019;s the method name, not the method itself, that is either public or private.\n\nWhen you redefine a method you don&#x2019;t really change the method. Instead you define a new method and attach an existing name to that new method.\n\nYou can explicitly prevent an object from being extended it by &#x201C;freezing&#x201D; it using the freeze method.\n