Copy Source | Copy HTML<br/> module Yaffle<br/> def self .included(base)<br/> base.send :extend, ClassMethods<br/> end <br/> <br/> module ClassMethods<br/> # , , Hickwall <br/> def acts_as_something <br/> send : include , InstanceMethods<br/> end <br/> end <br/> <br/> module InstanceMethods<br/> # , , @hickwall <br/> end <br/> end <br/>acts_as_something method will be called in the class itself, which will give it access to the private include method.Copy Source | Copy HTML<br/> class ActiveRecord::Base <br/> include Yaffle<br/> end <br/> <br/> class Article < ActiveRecord::Base <br/> acts_as_yaffle<br/> end <br/>ClassMethodsClassMethods ) declares a method that includes InstanceMethodsacts_as_something in your code.Copy Source | Copy HTML<br/> module Yaffle<br/> # , , Hickwall <br/> def acts_as_something <br/> send : include , InstanceMethods<br/> end <br/> <br/> module InstanceMethods<br/> # , , @hickwall <br/> end <br/> end <br/>Copy Source | Copy HTML<br/> class ActiveRecord::Base <br/> extend Yaffle<br/> end <br/> <br/> class Article < ActiveRecord::Base <br/> acts_as_yaffle<br/> end <br/>include so that it behaves like extend if Ruby has both of them!Copy Source | Copy HTML<br/> module Yaffle<br/> # , , @hickwall, <br/> # , ! <br/> end <br/> <br/>Copy Source | Copy HTML<br/> class Article < ActiveRecord::Base <br/> include Yaffle<br/> end <br/> <br/>extend , which further includes the module) is two layers of abstraction around a simple inclusion in Ruby!Copy Source | Copy HTML<br/> module Yaffle<br/> def self .included(base)<br/> base.send :extend, ClassMethods<br/> end <br/> <br/> module ClassMethods<br/> def acts_as_yaffle (options = {})<br/> cattr_accessor :yaffle_text_field<br/> self .yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s<br/> end <br/> end <br/> end <br/> <br/> ActiveRecord::Base .send : include , Yaffle <br/>include , so that it behaves like extend (instead of just calling extend !).Copy Source | Copy HTML<br/> module Yaffle<br/> def acts_as_yaffle (options = {})<br/> cattr_accessor :yaffle_text_field<br/> self .yaffle_text_field = options[:yaffle_text_field].to_s || "last_squawk" <br/> end <br/> end <br/> <br/> ActiveRecord::Base .extend Yaffle <br/>acts_as_yaffle , since we offer additional options that could not be encapsulated using normal extend. (Mysterious phrase. In the original: In this case, it’s appropriate to use it. Please note ) .Copy Source | Copy HTML<br/> module Yaffle<br/> def self .included(base)<br/> base.send :extend, ClassMethods<br/> end <br/> <br/> module ClassMethods<br/> def acts_as_yaffle (options = {})<br/> cattr_accessor :yaffle_text_field<br/> self .yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s<br/> send : include , InstanceMethods<br/> end <br/> end <br/> <br/> module InstanceMethods<br/> def squawk (string)<br/> write_attribute( self . class .yaffle_text_field, string.to_squawk)<br/> end <br/> end <br/> end <br/> <br/> ActiveRecord::Base .send : include , Yaffle <br/>extend , and call send , although this is not necessary. Identical functionality:Copy Source | Copy HTML<br/> module Yaffle<br/> def acts_as_yaffle (options = {})<br/> cattr_accessor :yaffle_text_field<br/> self .yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s<br/> include InstanceMethods<br/> end <br/> <br/> module InstanceMethods<br/> def squawk (string)<br/> write_attribute( self . class .yaffle_text_field, string.to_squawk)<br/> end <br/> end <br/> end <br/> <br/> ActiveRecord::Base .extend Yaffle <br/>Copy Source | Copy HTML<br/> module Yaffle<br/> def squawk (string)<br/> write_attribute( self . class .yaffle_text_field, string.to_squawk)<br/> end <br/> end <br/> <br/> class ActiveRecord::Base <br/> def self .acts_as_yaffle(options = {})<br/> cattr_accessor :yaffle_text_field<br/> self .yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s<br/> include Yaffle<br/> end <br/> end <br/>ActiveRecord::Base , the previous code with additional modules and use extend not worse than simply reopening the class and adding the acts_as_yaffle method directly. Now you can put the squawk method right inside the Yaffle module, from where it can easily be embedded.include and extend without the false impression of the need for magic spells, the use of send and special modules such as ClassMethods to make the plugins work.Source: https://habr.com/ru/post/87651/
All Articles