Refinements in Ruby 2.1+

6bf91645fc931c4c7f3d5549c4b7e59e?s=47 Derrick Parkhurst
March 02, 2015
49

Refinements in Ruby 2.1+

6bf91645fc931c4c7f3d5549c4b7e59e?s=128

Derrick Parkhurst

March 02, 2015
Tweet

Transcript

  1. Refinements in Ruby 2.1+ The feature that no one wanted,

    people hate, and no one uses Derrick Parkhurst http://thirtysixthspan.com | @8bsn
  2. Some Basic Statistics module Statistics def self.sum(array) array.map(&:to_f).inject(&:+) end def

    self.mean(array) sum(array) / array.size.to_f end end number = [10, 43, 12, 32, 1, 0] puts Statistics.sum(number) # => 98.0 puts Statistics.mean(number) # => 16.333333333333332
  3. Ruby's Open Class System sentence = "the lazy dog jumped

    over the brown fox" puts sentence.upcase # => "THE LAZY DOG JUMPED OVER THE BROWN FOX" puts sentence.capitalize # => "The lazy dog jumped over the brown fox" class String def to_pig_latin self .split(/\s/) .map { |word| word.match(/([qwrtpdfghjklzxvbnm]*)(.*)/i) } .map { |matches| "#{matches[2]}#{matches[1]}ay" } .join(' ') end end puts sentence.to_pig_latin # => ethay azylay ogday umpedjay overay ethay ownbray oxfay
  4. Core Extensions class Hash # Slice a hash to include

    only the given keys. # Returns a hash containing the given keys. # # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b) # # => {:a=>1, :b=>2} # def slice(*keys) if respond_to?(:convert_key, true) keys.map! { |key| convert_key(key) } end keys.each_with_object(self.class.new) do |k, hash| hash[k] = self[k] if has_key?(k) end end end Active Support
  5. class Hash # Returns a new hash with only the

    given keys. # # h = {:a=>1, :b=>2, :c=>3} # h.slice(:a, :c) #=> {:a=>1, :c=>3} # def slice(*keep_keys) if block_given? each do |k, v| keep_keys << k if yield(k, v) end end hash = {} keep_keys.each do |key| hash[key] = fetch(key) if key?(key) end hash end Core Extensions Facets
  6. Descriptive Statistics Gem require 'descriptive_statistics' data = [2,6,9,3,5,1,8,3,6,9,2] data.number #

    => 11.0 data.sum # => 54.0 data.mean # => 4.909090909090909 data.median # => 5.0 data.variance # => 7.7190082644628095 data.standard_deviation # => 2.778310325442932
  7. Extending Enumerable module Enumerable def number self.size.to_f end def sum

    return self.inject(:+) end def mean self.sum / self.number end end # Array [1,2,3,4,5].mean # => 3.0 # Hash {:a=>1, :b=>2, :c=>3, :d=>4, :e=>5}.mean # => 3.0 # Set Set.new([1,2,3,4,5]).mean # => 3.0 # Range (1..5).mean # => 3.0
  8. Monkey Patching Active Support [5, 15, 10].sum # => 30

    ['foo', 'bar'].sum # => "foobar" [[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5] Descriptive Statistics [5, 15, 10].sum # => 30.0 ['foo', 'bar'].sum # => 0.0 [[1, 2], [3, 1, 5]].sum # => Error
  9. Dynamic Extension module ChildSpeak def to_pig_latin self .split(/\s/) .map {

    |word| word.match(/([qwrtpdfghjklzxvbnm]*)(.*)/i) } .map { |matches| "#{matches[2]}#{matches[1]}ay" } .join(' ') end end sentence = "the lazy dog jumped over the brown fox" sentence.extend(ChildSpeak) puts sentence.to_pig_latin # => ethay azylay ogday umpedjay overay ethay ownbray oxfay quote = "a rose is a rose is a rose" puts quote.to_pig_latin # => undefined method `to_pig_latin' for String
  10. Dynamic Descriptive Statistics require 'descriptive_statistics/safe' data = [2,6,9,3,5,1,8,3,6,9,2] data.extend(DescriptiveStatistics) #

    => [2, 6, 9, 3, 5, 1, 8, 3, 6, 9, 2] data.number # => 11.0 data.sum # => 54
  11. Refinements module ChildSpeak refine String do def to_pig_latin self .split(/\s/)

    .map { |word| word.match(/([qwrtpdfghjklzxvbnm]*)(.*)/i) } .map { |matches| "#{matches[2]}#{matches[1]}ay" } .join(' ') end end end begin sentence = "the lazy dog jumped over the brown fox" puts sentence.to_pig_latin rescue Exception => error puts error.message end # => undefined method `to_pig_latin' using ChildSpeak puts sentence.to_pig_latin # => ethay azylay ogday umpedjay overay ethay ownbray oxfay
  12. Lexical Scoping require './child_speak' class Child using ChildSpeak def greeting

    "it is a lovely day today" end def say_greeting puts greeting.to_pig_latin end end tommy = Child.new tommy.say_greeting # => itay isay aay ovelylay ayday odaytay puts tommy.greeting.to_pig_latin # => undefined method `to_pig_latin'
  13. More Lexical Scoping require './child' class Child def shout_greeting puts

    greeting.upcase.to_pig_latin end end tommy = Child.new tommy.shout_greeting # => undefined method `to_pig_latin'
  14. Refined Statistics require 'descriptive_statistics/refinement' class SomeServiceClass using DescriptiveStatistics::Refinement.new(Array) def self.calculate_something(array)

    array.standard_deviation end end [1,2,3].standard_deviation # => NoMethodError: undefined method `standard_deviation' for [1, 2, 3]:Array SomeServiceClass.calculate_something([1,2,3]) #=> 0.816496580927726
  15. Refinements in Ruby 2.1+ The feature that no one wanted,

    people hate, and no one uses Derrick Parkhurst http://thirtysixthspan.com | @8bsn