SlideShare a Scribd company logo
1 of 27
OOP,
  metaprogramming,
blocks, iterators, mix-
   ins, duck typing.
       Code style
       Code style
Anton Shemerey
• https://github.com/shemerey
• https://twitter.com/shemerey
• https://www.facebook.com/shemerey
• https://www.linkedin.com/in/shemerey
• shemerey@gmail.com
• etc.
Code style

• https://github.com/bbatsov/ruby-style-guide
• https://github.com/bbatsov/rails-style-guide
• Use two spaces per tab!
• explicit “return” - is evil
OOP - Everything is object,
  not quite but still...
“hello” - this is object too
 1
 2   a = "hello" # instance
 3   b = a.dup   # new object
 4
 5   # instance method (for object)
 6   class << a
                                  1
 7     def to_s
                                  2 def a.to_s
 8       "#{self} world"
                                  3   "#{self} world"
 9     end
                                  4 end
10
                                  5
11     def say_hello
                                  6 def a.say_hello
12       self.to_s
                                  7   self.to_s
13     end
                                  8 end
14   end
                                  9
15
16   a.to_s                              #   =>   "hello world"
17   b.to_s                              #   =>   "hello"
18   a.methods - b.methods               #   =>   [:say_hello]
19   a.class.methods - b.class.methods   #   =>   []
42 - this is object too

• 42.instance_variables # => []
• 42.instance_variable_set(:@hello, 'world')
• 42.instance_variables # => [:@hello]
• 42.object_id # => 85
true - this is object too
• true.instance_variables # => []
• true.instance_variable_set(:@false, true)
• true.instance_variables # => [:@false
• true.object_id # => 2
• false.object_id # => 0
• nil.object_id # => 4
Class
 3   class Point
 4     def initialize(x, y)
 5       @x, @y = x, y
 6     end
 7   end
 8
 9   if __FILE__ == $PROGRAM_NAME
10     puts Point.new(1, 10).inspect #<Point:0x0bf78 @x=1, @y=10>
11   end
attribute reader/writer
 1 class Point           1 class Point
 2   def initialize(x)   2   attr_accessor :x
 3     @x = x            3
 4   end                 4   def initialize(x)
 5                       5     @x = x
 6   def x               6   end
 7     @x                7 end
 8   end                 8
 9
10   def x=(x)
11     @x = x
12   end
13 end
14
1   module ReadWrite
 2     def rw(*params)                               # params = [:x, :y]
 3       params.each do |attr|
 4         define_method attr do                    #    def x
 5           instance_variable_get :"@#{attr}"      #     @x
 6         end                                      #    end
 7
 8         define_method :"#{attr}=(val)" do         #   def x=(val)
 9           instance_variable_set :"@#{attr}=", val #    @x=val
10         end                                       #   end
11       end
12     end
13   end
14
15   class Object
16     extend ReadWrite
17   end
18
19   class Point
20     rw :x, :y
21
22     def initialize(x)
23       @x = x
24     end
25   end
26
Class / Module

•   Module.ancestors
    •   # => [Module, Object, Kernel, BasicObject]

• Class.ancestors
   • # => [Class, Module, Object, Kernel, BasicObject]
class A; end

• new
• inheritance
• include class A - computer says no
• extend class A - computer says no
• computer says no - http://bit.ly/gQX24
module B; end

• new - computer says no
• inheritance - computer says no
• include B
• extend B
• computer says no - http://bit.ly/gQX24
include/extend
 1   module M                        1   module M
 2     def inst_method               2     def cl_method
 3       "instance"                  3       "instance"
 4     end                           4     end
 5   end                             5   end
 6                                   6
 7                                   7
 8   class Point                     8   class Point
 9     include M                     9     extend M
10   end                            10   end
11                                  11
12   if __FILE__ == $PROGRAM_NAME   12   if __FILE__ == $PROGRAM_NAME
13     puts Point.new.inst_method   13     puts Point.cl_method
14   end                            14   end
15                                  15
1   module M
 2     def self.included(base)
 3       base.extend(ClassMethods)
 4     end
 5
 6     # -- instance methods --
 7
 8     module ClassMethods
 9       # -- class methods --
10     end
11   end
12
13
14   class Point
15     include M
16
17     def initialize(x)
18       @x = x
19     end
20   end
Classes and
      Objects
• More information: http://bit.ly/YZBfmp
Ruby Blocks
1   %w[first second third].each do |item|
2       item.capitalize
3   end
4
5   %w[first second third].each { |i| i.upcase }
6
7   %w[first second third].each <<= block
Yield
1   require "ostruct"
 2   Point = Struct.new(:x, :y)
 3
 4   class PointList
 5     def initialize                   13   def each(block = Proc.new)
 6      @data = []                      14     for item in @data
 7     end                              15       block.call(item)
 8                                      16     end
 9     def <<(other)                    17   end
10       @data << other
11     end
12
13     def each                         13   def each(&block)
14       for item in @data              14     for item in @data
15         yield item <<<<<<<<<<<<      15       block.call(item)
16       end                            16     end
17     end                              17   end
18   end
19
20   if __FILE__ == $PROGRAM_NAME
21     list = PointList.new << Point.new(1,3) << Point.new(2,1)
22     list.each do |point|
23       puts point #<struct Point x=1, y=3>, #<struct Point x=2, y=1>
24     end
25   end
Enumerable
http://ru.wikibooks.org/wiki/Ruby/Справочник/Enumerable
 1 require "ostruct"
 2
 3 Point = Struct.new(:x, :y) do
 4   def distance
 5     Math.sqrt(x**2 + y**2)
 6   end
 7 end
 8
 9 class PointList
 include Enumerable <<<<<<<
10   # -- code omitted --
11
12   def each
13     for item in @data
14       yield item
15     end
16   end
17 end
18
19 if __FILE__ == $PROGRAM_NAME
20   list = PointList.new << Point.new(1,3) << Point.new(2,1) << Point.new(2,2)
21   list.sort_by(&:distance)
22   list.sort_by {|e| e.distance }
23 end
Comparable
   <=>
   1, 0, -1
   1, 0, -1
   1, 0, -1
Comparable
 1   require "ostruct"
 2
 3   Point = Struct.new(:x, :y) do
 4     include Comparable <<<<<<
 5
 6     def distance
 7       Math.sqrt(x**2 + y**2)
 8     end
 9
10     def <=>(other)
11       self.distance <=> other.distance
12     end
13   end
14
15   if __FILE__ == $PROGRAM_NAME
16     puts Point.new(1,3) == Point.new(2,1) # false
17     puts Point.new(1,3) == Point.new(3,1) # true
18     puts Point.new(2,3) >= Point.new(1,1) # true
19     puts Point.new(2,3) <= Point.new(1,1) # false
20     puts Point.new(2,2).between? Point.new(2,1), Point.new(2,3) #true
21   end
Mad Ruby
#to_proc (&)
1 class Symbol
2   def to_proc
3     Proc.new { |*args| args.shift.__send__(self, *args) }
4   end
5 end

19 if __FILE__ == $PROGRAM_NAME
20   list = PointList.new << Point.new(1,3) << Point.new(2,1) << Point.new(2,2)
21   list.sort_by(&:distance)
22   list.sort_by {|e| e.distance }
23 end

1 [1, 2, 3].map(&:to_s) # => ["1", "2", "3"]
2 [3, 4, 5].inject(&:*) # => 60
Advanced Examples
 1   File.open('nginx.log', 'r') do |file|    1   ActiveRecord::Base.transaction do
 2     while line = file.gets                 2     # -- code omitted --
 3       puts line                            3   end
 4     end                                    4
 5   end                                      5    # -- possible implementation --
 6                                            6   module ActiveRecord
 7    # -- possible implementation --         7     class Base
 8   class File                               8       def transaction
 9     def open(file, option)                 9         # -- start transaction
10       if block_given?                     10         yield
11         f = fopen(file, option)           11         # -- commit transaction
12         yield f                           12         rescue ActiveRecord::Rollback
13         f.close                           13         # -- roll back transaction
14       end                                 14         ensure
15     end                                   15         # -- close transaction
16   end                                     16       end
                                             17     end
                                             18   end
The End

More Related Content

What's hot

Functional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedSusan Potter
 
Function Call Optimization
Function Call OptimizationFunction Call Optimization
Function Call Optimizationppd1961
 
The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180Mahmoud Samir Fayed
 
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Codemotion
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Wilson Su
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...ssuserd6b1fd
 
The Ring programming language version 1.6 book - Part 34 of 189
The Ring programming language version 1.6 book - Part 34 of 189The Ring programming language version 1.6 book - Part 34 of 189
The Ring programming language version 1.6 book - Part 34 of 189Mahmoud Samir Fayed
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Codemotion
 
DevOpsCon 2021: Go Web Development 101
DevOpsCon 2021: Go Web Development 101DevOpsCon 2021: Go Web Development 101
DevOpsCon 2021: Go Web Development 101Jan Stamer
 
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...Codemotion
 
Elixir: the not-so-hidden path to Erlang
Elixir: the not-so-hidden path to ErlangElixir: the not-so-hidden path to Erlang
Elixir: the not-so-hidden path to ErlangLaura M. Castro
 
Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Kim Hunmin
 
entwickler.de Go Day: Go Web Development 101
entwickler.de Go Day: Go Web Development 101entwickler.de Go Day: Go Web Development 101
entwickler.de Go Day: Go Web Development 101Jan Stamer
 
Refactoring group 1 - chapter 3,4,6
Refactoring   group 1 - chapter 3,4,6Refactoring   group 1 - chapter 3,4,6
Refactoring group 1 - chapter 3,4,6Duy Lâm
 
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystembetterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystemJan Stamer
 
The Ring programming language version 1.6 book - Part 81 of 189
The Ring programming language version 1.6 book - Part 81 of 189The Ring programming language version 1.6 book - Part 81 of 189
The Ring programming language version 1.6 book - Part 81 of 189Mahmoud Samir Fayed
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPatrick Allaert
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parserkamaelian
 

What's hot (20)

Functional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids Applied
 
Function Call Optimization
Function Call OptimizationFunction Call Optimization
Function Call Optimization
 
The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180
 
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
 
The Ring programming language version 1.6 book - Part 34 of 189
The Ring programming language version 1.6 book - Part 34 of 189The Ring programming language version 1.6 book - Part 34 of 189
The Ring programming language version 1.6 book - Part 34 of 189
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
 
DevOpsCon 2021: Go Web Development 101
DevOpsCon 2021: Go Web Development 101DevOpsCon 2021: Go Web Development 101
DevOpsCon 2021: Go Web Development 101
 
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
 
Elixir: the not-so-hidden path to Erlang
Elixir: the not-so-hidden path to ErlangElixir: the not-so-hidden path to Erlang
Elixir: the not-so-hidden path to Erlang
 
Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Lexical environment in ecma 262 5
Lexical environment in ecma 262 5
 
entwickler.de Go Day: Go Web Development 101
entwickler.de Go Day: Go Web Development 101entwickler.de Go Day: Go Web Development 101
entwickler.de Go Day: Go Web Development 101
 
Refactoring group 1 - chapter 3,4,6
Refactoring   group 1 - chapter 3,4,6Refactoring   group 1 - chapter 3,4,6
Refactoring group 1 - chapter 3,4,6
 
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystembetterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
 
Perl6 one-liners
Perl6 one-linersPerl6 one-liners
Perl6 one-liners
 
The Ring programming language version 1.6 book - Part 81 of 189
The Ring programming language version 1.6 book - Part 81 of 189The Ring programming language version 1.6 book - Part 81 of 189
The Ring programming language version 1.6 book - Part 81 of 189
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parser
 
PHP7 is coming
PHP7 is comingPHP7 is coming
PHP7 is coming
 

Similar to Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style

Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v RubyJano Suchal
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Damien Seguy
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+ConFoo
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Pedro Cunha
 
Dataflow: Declarative concurrency in Ruby
Dataflow: Declarative concurrency in RubyDataflow: Declarative concurrency in Ruby
Dataflow: Declarative concurrency in RubyLarry Diehl
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouAndres Almiray
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming LanguageDuda Dornelles
 

Similar to Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style (20)

PythonOOP
PythonOOPPythonOOP
PythonOOP
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Tres Gemas De Ruby
Tres Gemas De RubyTres Gemas De Ruby
Tres Gemas De Ruby
 
Migrating legacy data
Migrating legacy dataMigrating legacy data
Migrating legacy data
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Ruby
RubyRuby
Ruby
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
 
Dataflow: Declarative concurrency in Ruby
Dataflow: Declarative concurrency in RubyDataflow: Declarative concurrency in Ruby
Dataflow: Declarative concurrency in Ruby
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and You
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 

Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style

  • 1. OOP, metaprogramming, blocks, iterators, mix- ins, duck typing. Code style Code style
  • 2. Anton Shemerey • https://github.com/shemerey • https://twitter.com/shemerey • https://www.facebook.com/shemerey • https://www.linkedin.com/in/shemerey • shemerey@gmail.com • etc.
  • 3. Code style • https://github.com/bbatsov/ruby-style-guide • https://github.com/bbatsov/rails-style-guide • Use two spaces per tab! • explicit “return” - is evil
  • 4. OOP - Everything is object, not quite but still...
  • 5. “hello” - this is object too 1 2 a = "hello" # instance 3 b = a.dup # new object 4 5 # instance method (for object) 6 class << a 1 7 def to_s 2 def a.to_s 8 "#{self} world" 3 "#{self} world" 9 end 4 end 10 5 11 def say_hello 6 def a.say_hello 12 self.to_s 7 self.to_s 13 end 8 end 14 end 9 15 16 a.to_s # => "hello world" 17 b.to_s # => "hello" 18 a.methods - b.methods # => [:say_hello] 19 a.class.methods - b.class.methods # => []
  • 6. 42 - this is object too • 42.instance_variables # => [] • 42.instance_variable_set(:@hello, 'world') • 42.instance_variables # => [:@hello] • 42.object_id # => 85
  • 7. true - this is object too • true.instance_variables # => [] • true.instance_variable_set(:@false, true) • true.instance_variables # => [:@false • true.object_id # => 2 • false.object_id # => 0 • nil.object_id # => 4
  • 8. Class 3 class Point 4 def initialize(x, y) 5 @x, @y = x, y 6 end 7 end 8 9 if __FILE__ == $PROGRAM_NAME 10 puts Point.new(1, 10).inspect #<Point:0x0bf78 @x=1, @y=10> 11 end
  • 9. attribute reader/writer 1 class Point 1 class Point 2 def initialize(x) 2 attr_accessor :x 3 @x = x 3 4 end 4 def initialize(x) 5 5 @x = x 6 def x 6 end 7 @x 7 end 8 end 8 9 10 def x=(x) 11 @x = x 12 end 13 end 14
  • 10. 1 module ReadWrite 2 def rw(*params) # params = [:x, :y] 3 params.each do |attr| 4 define_method attr do # def x 5 instance_variable_get :"@#{attr}" # @x 6 end # end 7 8 define_method :"#{attr}=(val)" do # def x=(val) 9 instance_variable_set :"@#{attr}=", val # @x=val 10 end # end 11 end 12 end 13 end 14 15 class Object 16 extend ReadWrite 17 end 18 19 class Point 20 rw :x, :y 21 22 def initialize(x) 23 @x = x 24 end 25 end 26
  • 11. Class / Module • Module.ancestors • # => [Module, Object, Kernel, BasicObject] • Class.ancestors • # => [Class, Module, Object, Kernel, BasicObject]
  • 12. class A; end • new • inheritance • include class A - computer says no • extend class A - computer says no • computer says no - http://bit.ly/gQX24
  • 13. module B; end • new - computer says no • inheritance - computer says no • include B • extend B • computer says no - http://bit.ly/gQX24
  • 14. include/extend 1 module M 1 module M 2 def inst_method 2 def cl_method 3 "instance" 3 "instance" 4 end 4 end 5 end 5 end 6 6 7 7 8 class Point 8 class Point 9 include M 9 extend M 10 end 10 end 11 11 12 if __FILE__ == $PROGRAM_NAME 12 if __FILE__ == $PROGRAM_NAME 13 puts Point.new.inst_method 13 puts Point.cl_method 14 end 14 end 15 15
  • 15. 1 module M 2 def self.included(base) 3 base.extend(ClassMethods) 4 end 5 6 # -- instance methods -- 7 8 module ClassMethods 9 # -- class methods -- 10 end 11 end 12 13 14 class Point 15 include M 16 17 def initialize(x) 18 @x = x 19 end 20 end
  • 16. Classes and Objects • More information: http://bit.ly/YZBfmp
  • 17. Ruby Blocks 1 %w[first second third].each do |item| 2 item.capitalize 3 end 4 5 %w[first second third].each { |i| i.upcase } 6 7 %w[first second third].each <<= block
  • 18. Yield
  • 19. 1 require "ostruct" 2 Point = Struct.new(:x, :y) 3 4 class PointList 5 def initialize 13 def each(block = Proc.new) 6 @data = [] 14 for item in @data 7 end 15 block.call(item) 8 16 end 9 def <<(other) 17 end 10 @data << other 11 end 12 13 def each 13 def each(&block) 14 for item in @data 14 for item in @data 15 yield item <<<<<<<<<<<< 15 block.call(item) 16 end 16 end 17 end 17 end 18 end 19 20 if __FILE__ == $PROGRAM_NAME 21 list = PointList.new << Point.new(1,3) << Point.new(2,1) 22 list.each do |point| 23 puts point #<struct Point x=1, y=3>, #<struct Point x=2, y=1> 24 end 25 end
  • 21. http://ru.wikibooks.org/wiki/Ruby/Справочник/Enumerable 1 require "ostruct" 2 3 Point = Struct.new(:x, :y) do 4 def distance 5 Math.sqrt(x**2 + y**2) 6 end 7 end 8 9 class PointList include Enumerable <<<<<<< 10 # -- code omitted -- 11 12 def each 13 for item in @data 14 yield item 15 end 16 end 17 end 18 19 if __FILE__ == $PROGRAM_NAME 20 list = PointList.new << Point.new(1,3) << Point.new(2,1) << Point.new(2,2) 21 list.sort_by(&:distance) 22 list.sort_by {|e| e.distance } 23 end
  • 22. Comparable <=> 1, 0, -1 1, 0, -1 1, 0, -1
  • 23. Comparable 1 require "ostruct" 2 3 Point = Struct.new(:x, :y) do 4 include Comparable <<<<<< 5 6 def distance 7 Math.sqrt(x**2 + y**2) 8 end 9 10 def <=>(other) 11 self.distance <=> other.distance 12 end 13 end 14 15 if __FILE__ == $PROGRAM_NAME 16 puts Point.new(1,3) == Point.new(2,1) # false 17 puts Point.new(1,3) == Point.new(3,1) # true 18 puts Point.new(2,3) >= Point.new(1,1) # true 19 puts Point.new(2,3) <= Point.new(1,1) # false 20 puts Point.new(2,2).between? Point.new(2,1), Point.new(2,3) #true 21 end
  • 25. #to_proc (&) 1 class Symbol 2 def to_proc 3 Proc.new { |*args| args.shift.__send__(self, *args) } 4 end 5 end 19 if __FILE__ == $PROGRAM_NAME 20 list = PointList.new << Point.new(1,3) << Point.new(2,1) << Point.new(2,2) 21 list.sort_by(&:distance) 22 list.sort_by {|e| e.distance } 23 end 1 [1, 2, 3].map(&:to_s) # => ["1", "2", "3"] 2 [3, 4, 5].inject(&:*) # => 60
  • 26. Advanced Examples 1 File.open('nginx.log', 'r') do |file| 1 ActiveRecord::Base.transaction do 2 while line = file.gets 2 # -- code omitted -- 3 puts line 3 end 4 end 4 5 end 5 # -- possible implementation -- 6 6 module ActiveRecord 7 # -- possible implementation -- 7 class Base 8 class File 8 def transaction 9 def open(file, option) 9 # -- start transaction 10 if block_given? 10 yield 11 f = fopen(file, option) 11 # -- commit transaction 12 yield f 12 rescue ActiveRecord::Rollback 13 f.close 13 # -- roll back transaction 14 end 14 ensure 15 end 15 # -- close transaction 16 end 16 end 17 end 18 end