Fortunately, I have already done most of refactoring examples. But these three examples are not, so that this book is useful for me.
- Introduce Class Annotation
- Replace Type Code with State/Strategy
- Introduce Expression Builder
>%JRUBY_HOME%\bin\jruby --2.0 --version jruby 1.7.4 (2.0.0) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.7.0_21-b11 [Windows 7-amd64]
irb(main):001:0> class Enumerator::Lazy
irb(main):002:1> def at(nth)
irb(main):003:2> self.drop(nth).first
irb(main):004:2> end
irb(main):005:1> def slice(lower, upper)
irb(main):006:2> self.drop(lower).take(upper - lower + 1)
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> require 'prime'
=> true
irb(main):010:0> twin_prime = Prime.lazy.each_cons(2).select{|p,r| r-p == 2}
=> #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: Prime>:each_cons(2)>:select>
irb(main):011:0> twin_prime.at 0
=> [3, 5]
irb(main):012:0> twin_prime.at 1
=> [5, 7]
irb(main):013:0> twin_prime.at 2
=> [11, 13]
irb(main):014:0> twin_prime.at 3
=> [17, 19]
irb(main):015:0> twin_prime.at 100
=> [3851, 3853]
class Enumerator::Lazy
def at(nth)
self.drop(nth).first
end
def slice(lower, upper)
self.drop(lower).take(upper - lower + 1)
end
end
irb(main):009:0> oneToFive = [1,2,3,4,5].lazy => #<Enumerator::Lazy: [1, 2, 3, 4, 5]> irb(main):010:0> oneToFive.at 1 => 2 irb(main):011:0> oneToFive.slice 1, 3 => #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3, 4, 5]>:drop(1)>:take(3)> irb(main):012:0> (oneToFive.slice 1, 3).to_a => [2, 3, 4]
require 'pathname'
def all_file_under(pathname)
pathname.each_child.find_all(&:directory?).reduce(pathname.each_child.find_all(&:file?)) do |accum, subpathname|
accum = Array[*accum, *all_file_under(subpathname)]
end
end
puts all_file_under(Pathname.new('C:\temp'))
C:\temp/AAAAA C:\temp/BBBBBB C:\temp/CCCCCCC C:\temp/DDD/EEEE ...
> open System.IO;;
> let rec allFilesUnder basePath =
- seq {
- yield! Directory.GetFiles(basePath)
- for subdir in Directory.GetDirectories(basePath) do
- yield! allFilesUnder subdir
- };;
val allFilesUnder : basePath:string -> seq<string>
> allFilesUnder @"C:\temp";;
val it : seq<string> =
seq
["C:\temp\AAAAA"; "C:\temp\BBBBBB";
"C:\temp\CCCCCCC"; "C:\temp\DDD\EEEE"; ...]
gem 'rails', '3.2.9'
gem 'rake', '~> 0.9'
require 'singleton'
# Fibonacci as Singleton class
class Fibonacci < Enumerator
include Singleton
def initialize
super { |y|
a = 0
b = 1
loop do
y << a
a, b = b, a + b
end
}
end
end
# define a refinement
module Nth
refine Enumerator do
def nth(n)
self.take(n+1).find.with_index { |elem, i| i == n }
end
end
end
begin
# there are no additional methods
puts Fibonacci.instance.lazy.nth(100)
rescue => e
puts e
end
#using refinments
using Nth
begin
# there is an additional method
puts Fibonacci.instance.lazy.nth(100)
rescue => e
puts e
end
$ cd /c/ruby-2.0.0 $ ./bin/ruby ~/fibonacci.rb undefined method `nth' for #<Enumerator::Lazy:0x26430d8> 354224848179261915075
Microsoft (R) F# Interactive version 11.0.50727.1 Copyright (c) Microsoft Corporation. All Rights Reserved. For help type #help;; > let fibonacci = Seq.cache <| Seq.unfold (fun (current, next) -> Some(current, (next, current + next))) (0I, 1I);; val fibonacci : seq> fibonacci |> Seq.nth 100;; val it : System.Numerics.BigInteger = 354224848179261915075 {IsEven = false; IsOne = false; IsPowerOfTwo = false; IsZero = false; Sign = 1;}
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> fibonacci = Enumerator.new { |y|
irb(main):003:1* a = 0
irb(main):004:1* b = 1
irb(main):005:1> loop do
irb(main):006:2* y << a
irb(main):007:2> a, b = b, a + b
irb(main):008:2> end
irb(main):009:1> }.lazy
=> #<Enumerator::Lazy: #<Enumerator: #<Enumerator::Generator:0x23cbbc0>:each>>
irb(main):010:0> def fibonacci.nth(n)
irb(main):011:1> self.take(n+1).find.with_index { |elem, i| i == n }
irb(main):012:1> end
=> nil
irb(main):013:0> fibonacci.nth(100)
=> 354224848179261915075$ irb -rfiber -rdate irb(main):001:0> next_firefox = Fiber.new do irb(main):002:1* ff5 = Date.new(2011, 6, 21) irb(main):003:1> ff_next = 6 irb(main):004:1> ff_next_date = ff5 + 7 * 8 irb(main):005:1> loop do irb(main):006:2* Fiber.yield ff_next, ff_next_date irb(main):007:2> ff_next += 1 irb(main):008:2> ff_plan_date = ff_next_date + 7 * 6 irb(main):009:2> ff_happy_holiday = Date.new(ff_next_date.year, 12, 25) irb(main):010:2> if ff_happy_holiday.year >= 2012 && (ff_next_date..ff_plan_date).include?(ff_happy_holiday) irb(main):011:3> ff_next_date = ff_plan_date + 7 irb(main):012:3> else irb(main):013:3* ff_next_date = ff_plan_date irb(main):014:3> end irb(main):015:2> end irb(main):016:1> end => #<Fiber:0x2dc0af8> irb(main):017:0> next_firefox_version, next_firefox_date = next_firefox.resume => [6, #<Date: 2011-08-16 ((2455790j,0s,0n),+0s,2299161j)>] irb(main):018:0> while (next_firefox_version < next_firefox_date.year) do irb(main):019:1> next_firefox_version, next_firefox_date = next_firefox.resume irb(main):020:1> end => nil irb(main):021:0> puts "The version equals release year", next_firefox_version, next_firefox_date The version equals release year 2277 2277-11-06 => nil
$ irb -rcmath irb(main):001:0> include CMath => Object irb(main):002:0> left_euler = exp(-1.0*sqrt(-1.0)*PI) => (-1.0-1.2246063538223773e-16i) irb(main):003:0> right_euler = cos(PI) + sqrt(-1.0) * sin(PI) => (-1.0+1.2246063538223773e-16i) irb(main):004:0> left_euler == right_euler => false irb(main):005:0> left_euler === right_euler => false
irb(main):001:0> require 'java' irb(main):002:0> import java.util.UUID irb(main):003:0> UUID.randomUUID.to_s => "e42ccfce-d6a0-4cb5-a0c0-9fae6ca05b84" irb(main):003:0> UUID.randomUUID.to_s => "80a31bb3-3fce-4e6f-9c8a-5a819de45960"
[1] pry(main)> require 'securerandom' => true [2] pry(main)> SecureRandom.hex => "444adf4fe82c00ab6d9a7cdffc6d46e1" [3] pry(main)> SecureRandom.base64 => "B4hdEsaM3icerGi2/LIEFw==" [4] pry(main)> SecureRandom.urlsafe_base64 => "--gOBG02VkWhimQz-6mVyA" [5] pry(main)> SecureRandom.uuid => "da3488c8-0aca-45d0-bd60-d2d1a1df1a02"