Active Support Core Extensions (1)
description
Transcript of Active Support Core Extensions (1)
Active SupportCore Extensions
ROR lab. DD-1- The 1st round -
March 16, 2013
Hyoseong Choi
• Ruby on Rails components
• actionmailer
• actionpack
• activerecord
• activesupport ...
Active Support
• Ruby on Rails components
• actionmailer
• actionpack
• activerecord
• activesupport ...
Active Support
Active Support
• Ruby language extensions
• Utility classes
• Other transversal stuff
Core ExtensionsStand-Alone Active Support
require 'active_support'
“blank?” method
Grouped Core Extensionsrequire 'active_support/core_ext/object'
All Core Extensionsrequire 'active_support/core_ext'
All Active Supportrequire 'active_support/all'
require 'active_support/core_ext/object/blank'
Cherry-picking
Core ExtensionsActive Support within ROR Application
require 'active_support/all'
Default
config.active_support.bare = true
Barebone setting with Cherry-pickings
Ext. to All Objects• blank?
‣ nil and false
‣ whitespaces : spaces, tabs, newlines
‣ empty arrays and hashes
‣ empty? true
• present?
‣ !blank?
0 and 0.0
!blank
active_support/core_ext/object/blank.rb
Ext. to All Objects• presence
host = config[:host].presence || 'localhost'
active_support/core_ext/object/blank.rb
Ext. to All Objects
active_support/core_ext/object/duplicable.rb
• duplicable?
"".duplicable? # => truefalse.duplicable? # => false
Singletons : nil, false, true, symobls, numbers, and class and module objects
Ext. to All Objects
active_support/core_ext/object/try.rb
• try
def log_info(sql, name, ms) if @logger.try(:debug?) name = '%s (%.1fms)' % [name || 'SQL', ms] @logger.debug(format_log_entry(name, sql.squeeze(' '))) endend
@person.try { |p| "#{p.first_name} #{p.last_name}" }
• try!
Ext. to All Objects
active_support/core_ext/kernel/singleton_class.rb
• singleton_class
nil => NilClasstrue => TrueClassfalse => FalseClass
Singleton Class?• When you add a method to a specific object, Ruby inserts
a new anonymous class into the inheritance hierarchy as a container to hold these types of methods.
http://www.devalot.com/articles/2008/09/ruby-singleton
anonymous
class
foobar = [ ]def foobar.say “Hello”end
Singleton Class?
http://www.devalot.com/articles/2008/09/ruby-singleton
anonymous
class
module Foo def foo "Hello World!" endend
foobar = []foobar.extend(Foo)foobar.singleton_methods # => ["foo"]
foobar = []
class << foobar def foo "Hello World!" endend
foobar.singleton_methods # => ["foo"]
foobar = []
foobar.instance_eval <<EOT def foo "Hello World!" endEOT foobar.singleton_methods # => ["foo"]
foobar = Array.new
def foobar.size "Hello World!"endfoobar.size # => "Hello World!"foobar.class # => Arraybizbat = Array.newbizbat.size # => 0
Singleton Class?
http://www.devalot.com/articles/2008/09/ruby-singleton
class Foo def self.one () 1 end class << self def two () 2 end end
def three () 3 end self.singleton_methods # => ["two", "one"] self.class # => Class self # => Fooend
• Practical Uses of Singleton Classes
classmethod
classmethod
anonymous
class
Ext. to All Objects
active_support/core_ext/kernel/singleton_class.rb
• class_eval(*args, &block)
class Proc def bind(object) block, time = self, Time.now object.class_eval do method_name = "__bind_#{time.to_i}_#{time.usec}" define_method(method_name, &block) method = instance_method(method_name) remove_method(method_name) method end.bind(object) endend
Ext. to All Objects
active_support/core_ext/object/acts_likes.rb
• acts_like?(duck)
some_klass.acts_like?(:string)
same interface?
def acts_like_string?end
acts_like_date? (Date class)acts_like_time? (Time class)
for
example
Ext. to All Objects
active_support/core_ext/object/to_param.rb
• to_param(=> to_s) a value for :id placeholder
class User def to_param "#{id}-#{name.parameterize}" endend
user_path(@user) # => "/users/357-john-smith"➧
=> The return value should not be escaped!
overwriting
Ext. to All Objects
active_support/core_ext/object/to_query.rb
• to_query a value for :id placeholder
class User def to_param "#{id}-#{name.parameterize}" endend
current_user.to_query('user') # => user=357-john-smith➧
=> escaped!
Ext. to All Objects
active_support/core_ext/object/to_query.rb
• to_queryescaped
account.to_query('company[name]')# => "company%5Bname%5D=Johnson+%26+Johnson"
{:c => 3, :b => 2, :a => 1}.to_query # => "a=1&b=2&c=3"
[3.4, -45.6].to_query('sample')# => "sample%5B%5D=3.4&sample%5B%5D=-45.6"
{:id => 89, :name => "John Smith"}.to_query('user')# => "user%5Bid%5D=89&user%5Bname%5D=John+Smith"
Ext. to All Objects
active_support/core_ext/object/with_options.rb
• with_options
class Account < ActiveRecord::Base has_many :customers, :dependent => :destroy has_many :products, :dependent => :destroy has_many :invoices, :dependent => :destroy has_many :expenses, :dependent => :destroyend
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 endend
Ext. to All Objects
active_support/core_ext/object/with_options.rb
• with_options
I18n.with_options locale: user.locale, scope: "newsletter" do |i18n| subject i18n.t(:subject) body i18n.t(:body, user_name: user.name)end
# app/views/home/index.html.erb<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %> # config/locales/en.ymlen: greet_username: "%{message}, %{user}!"
http://guides.rubyonrails.org/i18n.html
interpolation key
Ext. to All Objects
active_support/core_ext/object/with_options.rb
• with_options
en: activerecord: models: user: Dude attributes: user: login: "Handle" # will translate User attribute "login" as "Handle"
http://guides.rubyonrails.org/i18n.html
scope ofi18n
config/locales/en.yml
Ext. to All Objects
active_support/core_ext/object/instance_variable.rb
• Instance Variables
class C def initialize(x, y) @x, @y = x, y endend C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
Ext. to All Objects
active_support/core_ext/kernel/reporting.rb
• Silencing Warnings, Streams, and Exceptions
silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
silence_stream(STDOUT) do # STDOUT is silent hereend
quietly { system 'bundle install' }
# If the user is locked the increment is lost, no big deal.suppress(ActiveRecord::StaleObjectError) do current_user.increment! :visitsend
$VERBOSE
even in
subprocessessilencing
exceptions
silencingstreams
Ext. to All Objects
active_support/core_ext/object/inclusion.rb
• in?1.in?(1,2) # => true1.in?([1,2]) # => true"lo".in?("hello") # => true25.in?(30..50) # => false1.in?(1) # => ArgumentError
[1,2].include? 1 # => true"hello".include? "lo" # => true(30..50).include? 25 # => false
• include? (array method)
ROR Lab.
�������