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 ActiveSupport
require 'active_support'
# load all the core extensions
require 'active_support/core_ext'
# load grouped extensions require 'active_support/core_ext/object'
# Cherry-pick
require '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 methods
delegate :name, :age, :address, :twitter, to: :profile
# Handle the cunning nil!
delegate :name, to: :profile, allow_nil: true
# Set prefix ie., address_street
delegate :street, to: :address, prefix: true
# Custom prefix
delegate :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: '…') # => "Oh dear! Oh …"
"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.rbactive_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,612