slides.each do |slide|

ActiveSupport Core Extensions



Kerala Ruby User Group Meetup
March 16, 2014


Active Support is the Ruby on Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff.


It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Ruby on Rails itself.

Hello, I am Akhil Stanislavose


  • Works @ MobME Wireless
  • Rubyist / JavaScript Maniac / Objective-C Noob
  • Computer Science Enthusiast

Loading Extensions



# load the whole ActiveSupportrequire 'active_support'

# load all the core extensionsrequire 'active_support/core_ext'

# load grouped extensions require 'active_support/core_ext/object'

# Cherry-pickrequire 'active_support/core_ext/object/blank'

blank? and present?


nil.blank?#=> true false.blank? #=> true
''.blank?  #=> true
[].blank?  #=> true {}.blank?  #=> true
active_support/core_ext/object/blank.rb

try


When you want to call a method on an object only if it is not nil

# without try
unless @number.nil?
  @number.next
end
 
# with try
@number.try(:next)
# Accepts block too!@person.try { |p| "#{p.first_name} #{p.last_name}" }

active_support/core_ext/object/try.rb

with_options

Refactor:
class Account < ActiveRecord::Base
  has_many :customers, dependent: :destroy
  has_many :products,  dependent: :destroy
  has_many :invoices,  dependent: :destroy
  has_many :expenses,  dependent: :destroy
end
into:
class Account < ActiveRecord::Base
  with_options dependent: :destroy do |assoc|
    assoc.has_many :customers
    assoc.has_many :products
    assoc.has_many :invoices
    assoc.has_many :expenses
  end
end

active_support/core_ext/object/with_options.rb

Silencing Warnings, Streams, and Exceptions


silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }

silence_stream(STDOUT) do
  # STDOUT is silent here
end

quietly { system 'bundle install' }
# If the user is locked the increment is lost, no big deal. suppress(ActiveRecord::StaleObjectError) do current_user.increment! :visits end

active_support/core_ext/kernel/reporting.rb

Method Delegation

Refactor:
 class User < ActiveRecord::Base
  has_one :profile
 
  def name
    profile.name
  end
end
Into:
 class User < ActiveRecord::Base
  has_one :profile
 
  delegate :name, to: :profile
end

active_support/core_ext/module/delegation.rb

Method Delegation...



# Delegate several methodsdelegate :name, :age, :address, :twitter, to: :profile

# Handle the cunning nil!delegate :name, to: :profile, allow_nil: true

# Set prefix ie., address_streetdelegate :street, to: :address, prefix: true

# Custom prefixdelegate :size, to: :attachment, prefix: :avatar

squish, truncate, inquiry



" \n foo\n\r \t bar \n".squish # => "foo bar"

"Oh dear! Oh dear! I shall be late!".truncate(20) # => "Oh dear! Oh dear!..."

"Oh dear! Oh dear! I shall be late!".truncate(20, omission: '&hellip;') # => "Oh dear! Oh &hellip;"

"production".inquiry.production? # => true "active".inquiry.inactive?       # => false


active_support/core_ext/string/filters.rb

indent


<<EOS.indent(2)
def some_method
  some_code
end
EOS
# =>
  def some_method
    some_code
  end
"  foo".indent(2)        # => "    foo" "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar" "foo".indent(2, "\t")    # => "\t\tfoo"

"foo\n\nbar".indent(2)            # => "  foo\n\n  bar" "foo\n\nbar".indent(2, nil, true) # => "  foo\n  \n  bar"
active_support/core_ext/string/indent.rb

constantize



"Fixnum".constantize # => Fixnum   module M   X = 1 end "M::X".constantize # => 1

active_support/core_ext/string/inflections.rb

to_s

1234567890.50.to_s(:currency) 
12345678.to_s(:delimited)                     # => 12,345,678 12345678.to_s(:delimited, delimiter: ".")     # => 12.345.678

123.to_s(:human_size)            # => 123 Bytes 1234.to_s(:human_size)           # => 1.21 KB 12345.to_s(:human_size)          # => 12.1 KB

123.to_s(:human)               # => "123" 1234.to_s(:human)              # => "1.23 Thousand" 12345.to_s(:human)             # => "12.3 Thousand" 1234567.to_s(:human)           # => "1.23 Million"
2.multiple_of?(1) # => true 1.multiple_of?(2) # => false

active_support/core_ext/numeric/formatting.rb

sum



[1, 2, 3].sum # => 6 (1..100).sum  # => 5050

[[1, 2], [2, 3], [3, 4]].sum    # => [1, 2, 2, 3, 3, 4] %w(foo bar baz).sum             # => "foobarbaz" {a: 1, b: 2, c: 3}.sum # => [:b, 2, :c, 3, :a, 1]

(1..5).sum {|n| n * 2 } # => 30 [2, 4, 6, 8, 10].sum    # => 30

[].sum(1) {|n| n**3} # => 1


active_support/core_ext/enumerable.rb

index_by, many?, exclude?



invoices.index_by(&:number) # => {'2009-032' => <Invoice ...>, '2009-008' => <Invoice ...>, ...}

<% if pages.many? %>   <%= pagination_links %> <% end %>

@see_more = videos.many? {|video| video.category == params[:category]}

to_visit << node if visited.exclude?(node)


active_support/core_ext/enumerable.rb

in_groups_of, split


[1, 2, 3].in_groups_of(2) # => [[1, 2], [3, nil]]

[1, 2, 3, 4].in_groups_of(2) do |a, b| p "#{a} and #{b}" end
[1, 2, 3].in_groups_of(2, 0) # => [[1, 2], [3, 0]][1, 2, 3].in_groups_of(2, false) # => [[1, 2], [3]]
(-5..5).to_a.split { |i| i.multiple_of?(4) } # => [[-5], [-3, -2, -1], [1, 2, 3], [5]] [0, 1, -5, 1, 1, "foo", "bar"].split(1) # => [[0], [-5], [], ["foo", "bar"]]

active_support/core_ext/array/grouping.rb

except, slice, extract!


{a: 1, b: 2}.except(:a) # => {:b=>2}

{a: 1, b: 2, c: 3}.slice(:a, :c) # => {:c=>3, :a=>1}   {a: 1, b: 2, c: 3}.slice(:b, :X) # => {:b=>2} # non-existing keys are ignored

hash = {a: 1, b: 2} rest = hash.extract!(:a) # => {:a=>1} hash                     # => {:b=>2}

active_support/core_ext/hash/except.rb
active_support/core_ext/hash/slice.rb

transform_, stringify_, symbolize_

{nil => nil, 1 => 1, a: :a}.transform_keys{ |key| key.to_s.upcase }
# => {"" => nil, "A" => :a, "1" => 1}
{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_transform_keys{ |key| key.to_s.upcase } # => {""=>nil, "1"=>1, "NESTED"=>{"A"=>3, "5"=>5}}'

{nil => nil, 1 => 1, a: :a}.stringify_keys # => {"" => nil, "a" => :a, "1" => 1}

{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_stringify_keys # => {""=>nil, "1"=>1, "nested"=>{"a"=>3, "5"=>5}}

{nil => nil, 1 => 1, "a" => "a"}.symbolize_keys # => {1=>1, nil=>nil, :a=>"a"}

{nil => nil, 1 => 1, "nested" => {"a" => 3, 5 => 5}}.deep_symbolize_keys # => {nil=>nil, 1=>1, nested:{a:3, 5=>5}}
active_support/core_ext/hash/keys.rb

with_indifferent_access


{a: 1}.with_indifferent_access["a"] # => 1
{a: 1, 'b' => 2}.with_indifferent_access[:b] # => 2

active_support/core_ext/hash/indifferent_access.rb

and many more...


  • Extensions to Regexp
  • Extensions to Range
  • Extensions to Proc
  • Extensions to Date
  • Extensions to DateTime
  • Extensions to Time
  • Extensions to File
  • Extensions to Marshal
  • Extensions to Logger
  • Extensions to NameError
  • Extensions to LoadError



What else is there in ActiveSupport?





end

questions.any?

ActiveSupport Core Extensions

By akhil stanislavose

ActiveSupport Core Extensions

  • 1,473