Active SupportCore Extensions (2)
ROR lab. DD-1- The 2nd round -
April 13, 2013
Hyoseong Choi
Ext. to Module• alias_method_chain
active_support/core_ext/module/aliasing.rb
• “alias chaining”? ➧ wrapping
http://erniemiller.org/2011/02/03/when-to-use-alias_method_chain/
ActionController::TestCase.class_eval do def process_with_stringified_params(...) params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten] process_without_stringified_params(action, params, session, flash, http_method) end alias_method_chain :process, :stringified_paramsend
Ext. to Module• alias_attribute
active_support/core_ext/module/aliasing.rb
class User < ActiveRecord::Base # let me refer to the email column as "login", # possibly meaningful for authentication code alias_attribute :login, :emailend
Ext. to Module• attr_accessor_with_default
active_support/core_ext/module/attr_accessor_with_default.rb
class Url attr_accessor_with_default :port, 80end Url.new.port # => 80
class User attr_accessor :name, :surname attr_accessor_with_default(:full_name) do [name, surname].compact.join(" ") endend u = User.newu.name = 'Xavier'u.surname = 'Noria'u.full_name # => "Xavier Noria"
not cached
Ext. to Module• attr_internal or attr_internal_accessor
active_support/core_ext/module/attr_internal.rb
# libraryclass ThirdPartyLibrary::Crawler attr_internal :log_levelend # client codeclass MyCrawler < ThirdPartyLibrary::Crawler attr_accessor :log_levelend
@_log_level
Module.attr_internal_naming_format = “@_%s”
sprintf-like format
Ext. to Module• attr_internal or attr_internal_accessor
active_support/core_ext/module/attr_internal.rb
module ActionView class Base attr_internal :captures attr_internal :request, :layout attr_internal :controller, :template endend
Ext. to Module• mattr_accessor
active_support/core_ext/module/attr_accessors.rb
module ActiveSupport module Dependencies mattr_accessor :warnings_on_first_load mattr_accessor :history mattr_accessor :loaded mattr_accessor :mechanism mattr_accessor :load_paths mattr_accessor :load_once_paths mattr_accessor :autoloaded_constants mattr_accessor :explicitly_unloadable_constants mattr_accessor :logger mattr_accessor :log_activity mattr_accessor :constant_watch_stack mattr_accessor :constant_watch_stack_mutex endend
• cattr_accessor
Ext. to Module
• Parents
active_support/core_ext/module/introspection.rb
• parent
• parent_name
• parents
Ext. to Module• Parents
active_support/core_ext/module/introspection.rb
module X module Y module Z end endendM = X::Y::Z X::Y::Z.parent # => X::YM.parent # => X::Y
• parent
Ext. to Module• Parents
active_support/core_ext/module/introspection.rb
• parent_name
module X module Y module Z end endendM = X::Y::Z X::Y::Z.parent_name # => "X::Y"M.parent_name # => "X::Y"
Ext. to Module• Parents
active_support/core_ext/module/introspection.rb
• parents
module X module Y module Z end endendM = X::Y::Z X::Y::Z.parents # => [X::Y, X, Object]M.parents # => [X::Y, X, Object]
Ext. to Module• local_constants
module X X1 = 1 X2 = 2 module Y Y1 = :y1 X1 = :overrides_X1_above endend X.local_constants # => ["X2", "X1", "Y"], assumes Ruby 1.8X::Y.local_constants # => ["X1", "Y1"], assumes Ruby 1.8
active_support/core_ext/module/introspection.rb
• local_constant_names ⟶ always, strings
as symbols in Ruby 1.9
deprecated!!!
Ext. to Module• const_defined? /_get /_set
Math.const_defined? "PI" #=> trueIO.const_defined? :SYNC #=> trueIO.const_defined? :SYNC, false #=> false
active_support/core_ext/module/introspection.rb
Math.const_get(:PI) #=> 3.14159265358979
Math.const_set("HIGH_SCHOOL_PI", 22.0/7.0) #=> 3.14285714285714Math::HIGH_SCHOOL_PI - Math::PI #=> 0.00126448926734968
standard ruby methods
bare constant names
Ext. to Module• const_defined? /_get /_set
module Foo class Bar VAL = 10 end
class Baz < Bar; endend
Object.const_get 'Foo::Baz::VAL' # => 10Object.const_get 'Foo::Baz::VAL', false # => NameError
active_support/core_ext/module/introspection.rb
standard ruby methods
bare constant names
flag for inherit
Ext. to Module• qualified_const_defined? /_get /_set
module M X = 1end module N class C include M endend
active_support/core_ext/module/qualified_const.rb
new extended methods
N.qualified_const_defined?("C::X", false) N.qualified_const_defined?("C::X", true) N.qualified_const_defined?("C::X")
relative to their receiver
qualified constant names
Ext. to Module• synchronize
class Counter @@mutex = Mutex.new attr_reader :value def initialize @value = 0 end def incr @value += 1 # non-atomic end synchronize :incr, :with => '@@mutex'end
active_support/core_ext/module/synchronization.rb
DEPRECATION WARNING: synchronize is deprecated and will be removed from Rails 4.0.
Ext. to Module• reachable?
module Mend M.reachable? # => true
orphan = Object.send(:remove_const, :M) # The module object is orphan now but it still has a name.orphan.name # => "M" # You cannot reach it via the constant M because it does not even exist.orphan.reachable? # => false # Let's define a module called "M" again.module Mend # The constant M exists now again, and it stores a module# object called "M", but it is a new instance.orphan.reachable? # => false
active_support/core_ext/module/reachable.rb
The constant M exists now, and it stores a module object called "M"
Ext. to Module• anonymous?
module MendM.name # => "M" N = Module.newN.name # => "N" Module.new.name # => "" in 1.8, nil in 1.9
M.anonymous? # => false Module.new.anonymous? # => true
m = Object.send(:remove_const, :M) m.reachable? # => falsem.anonymous? # => false
active_support/core_ext/module/anonymous.rb
Ext. to Module• delegate
class User < ActiveRecord::Base has_one :profileend
class User < ActiveRecord::Base has_one :profile def name profile.name endend
class User < ActiveRecord::Base has_one :profile delegate :name, :to => :profileend
delegate :name, :age, :address, :twitter, :to => :profiledelegate :name, :to => :profile, :allow_nil => truedelegate :street, :to => :address, :prefix => truedelegate :size, :to => :attachment, :prefix => :avatar
active_support/core_ext/module/delegation.rb
Ext. to Module• redefine_method
redefine_method("#{reflection.name}=") do |new_value| association = association_instance_get(reflection.name) if association.nil? || association.target != new_value association = association_proxy_class.new(self, reflection) end association.replace(new_value) association_instance_set(reflection.name, new_value.nil? ? nil : association)end
active_support/core_ext/module/remove_method.rb
ROR Lab.
감사합니다.����������� ������������������