- 浏览: 2054386 次
- 性别:
- 来自: NYC
文章分类
- 全部博客 (628)
- Linux (53)
- RubyOnRails (294)
- HTML (8)
- 手册指南 (5)
- Mysql (14)
- PHP (3)
- Rails 汇总 (13)
- 读书 (22)
- plugin 插件介绍与应用 (12)
- Flex (2)
- Ruby技巧 (7)
- Gem包介绍 (1)
- javascript Jquery ext prototype (21)
- IT生活 (6)
- 小工具 (4)
- PHP 部署 drupal (1)
- javascript Jquery sort plugin 插件 (2)
- iphone siri ios (1)
- Ruby On Rails (106)
- 编程概念 (1)
- Unit Test (4)
- Ruby 1.9 (24)
- rake (1)
- Postgresql (6)
- ruby (5)
- respond_to? (1)
- method_missing (1)
- git (8)
- Rspec (1)
- ios (1)
- jquery (1)
- Sinatra (1)
最新评论
-
dadadada2x:
user模型里加上 protected def email ...
流行的权限管理 gem devise的定制 -
Sev7en_jun:
shrekting 写道var pattern = /^(0| ...
强悍的ip格式 正则表达式验证 -
jiasanshou:
好文章!!!
RPM包rpmbuild SPEC文件深度说明 -
寻得乐中乐:
link_to其实就是个a标签,使用css控制,添加一个参数: ...
Rails在link_to中加参数 -
aiafei0001:
完全看不懂,不知所然.能表达清楚一点?
"$ is not defined" 的问题怎么办
Posted 3 days back at RailsTips.org - Home
In which I show the difference between include and extend when working with modules in Ruby.
Now that we know the difference between an instance method and a class method, let’s cover the difference between include and extend in regards to modules. Include is for adding methods to an instance of a class and extend is for adding class methods. Let’s take a look at a small example.
module Foo
def foo
puts 'heyyyyoooo!'
end
end
class Bar
include Foo
end
Bar.new.foo # heyyyyoooo!
Bar.foo # NoMethodError: undefined method ‘foo’ for Bar:Class
class Baz
extend Foo
end
Baz.foo # heyyyyoooo!
Baz.new.foo # NoMethodError: undefined method ‘foo’ for #<Baz:0x1e708>
As you can see, include makes the foo method available to an instance of a class and extend makes the foo method available to the class itself.
Include Example
If you want to see more examples of using include to share methods among models, you can read my article on how I added simple permissions to an app. The permissions module in that article is then included in a few models thus sharing the methods in it. That is all I’ll say here, so if you want to see more check out that article.
Extend Example
I’ve also got a simple example of using extend that I’ve plucked from the Twitter gem. Basically, Twitter supports two methods for authentication—httpauth and oauth. In order to share the maximum amount of code when using these two different authentication methods, I use a lot of delegation. Basically, the Twitter::Base class takes an instance of a “client”. A client is an instance of either Twitter::HTTPAuth or Twitter::OAuth.
Anytime a request is made from the Twitter::Base object, either get or post is called on the client. The Twitter::HTTPAuth client defines the get and post methods, but the Twitter::OAuth client does not. Twitter::OAuth is just a thin wrapper around the OAuth gem and the OAuth gem actually provides get and post methods on the access token, which automatically handles passing the OAuth information around with each request.
The implementation looks something like this (full file on github):
module Twitter
class OAuth
extend Forwardable
def_delegators :access_token, :get, :post
# a bunch of code removed for clarity
end
end
Rather than define get and post, I simply delegate the get and post instance methods to the access token, which already has them defined. I do that by extending the Forwardable module onto the Twitter::OAuth class and then using the def_delegators class method that it provides. This may not be the most clear example, but it was the first that came to mind so I hope it is understandable.
A Common Idiom
Even though include is for adding instance methods, a common idiom you’ll see in Ruby is to use include to append both class and instance methods. The reason for this is that include has a self.included hook you can use to modify the class that is including a module and, to my knowledge, extend does not have a hook. It’s highly debatable, but often used so I figured I would mention it. Let’s look at an example.
module Foo
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def bar
puts 'class method'
end
end
def foo
puts 'instance method'
end
end
class Baz
include Foo
end
Baz.bar # class method
Baz.new.foo # instance method
Baz.foo # NoMethodError: undefined method ‘foo’ for Baz:Class
Baz.new.bar # NoMethodError: undefined method ‘bar’ for #<Baz:0x1e3d4>
There are a ton of projects that use this idiom, including Rails, DataMapper, HTTParty, and HappyMapper. For example, when you use HTTParty, you do something like this.
class FetchyMcfetcherson
include HTTParty
end
FetchyMcfetcherson.get('http://foobar.com')
When you add the include to your class, HTTParty appends class methods, such as get, post, put, delete, base_uri, default_options and format. I think this idiom is what causes a lot of confusion in the include verse extend understanding. Because you are using include it seems like the HTTParty methods would be added to an instance of the FetchyMcfetcherson class, but they are actually added to the class itself.
Conclusion
Hope this helps those struggling with include verse extend. Use include for instance methods and extend for class methods. Also, it is sometimes ok to use include to add both instance and class methods. Both are really handy and allow for a great amount of code reuse. They also allow you to avoid deep inheritance, and instead just modularize code and include it where needed, which is much more the ruby way.
发表评论
-
Destroying a Postgres DB on Heroku
2013-04-24 10:58 897heroku pg:reset DATABASE -
VIM ctags setup ack
2012-04-17 22:13 3224reference ctags --extra=+f --e ... -
alias_method_chain方法在3.1以后的替代使用方式
2012-02-04 02:14 3249alias_method_chain() 是rails里的一个 ... -
一些快速解决的问题
2012-01-19 12:35 1443问题如下: 引用Could not open library ... -
API service 安全问题
2011-12-04 08:47 1347这是一个长期关注的课题 rest api Service的 ... -
Module方法调用好不好
2011-11-20 01:58 1309以前说,用module给class加singleton方法,和 ... -
一个ajax和rails交互的例子
2011-11-19 01:53 1866首先,这里用了一个,query信息解析的包,如下 https: ... -
Rails 返回hash给javascript
2011-11-19 01:43 2244这是一个特别的,不太正统的需求, 因为,大部分时候,ajax的 ... -
关于Rubymine
2011-11-18 23:21 2234开个帖子收集有关使用上的问题 前一段时间,看到半价就买了。想 ... -
ruby中和javascript中,动态方法的创建
2011-11-18 21:01 1198class Klass def hello(*args) ... -
textmate快捷键 汇总
2011-11-16 07:20 8097TextMate 列编辑模式 按住 Alt 键,用鼠标选择要 ... -
Ruby面试系列六,面试继续面试
2011-11-15 05:55 1988刚才受到打击了,充分报漏了自己基础不扎实,不肯向虎炮等兄弟学习 ... -
说说sharding
2011-11-13 00:53 1447这个东西一面试就有人 ... -
rails面试碎碎念
2011-11-12 23:51 1909面试继续面试 又有问ru ... -
最通常的git push reject 和non-fast forward是因为
2011-11-12 23:29 17163git push To git@github.com:use ... -
Rails 自身的many to many关系 self has_many
2011-11-12 01:43 2687简单点的 #注意外键在person上people: id ... -
Rails 3下的 in place editor edit in place
2011-11-12 01:20 919第一个版本 http://code.google.com/p ... -
Heroku 的诡异问题集合
2011-11-11 07:22 1665开个Post记录,在用heroku过程中的一些诡异问题和要注意 ... -
SCSS 和 SASS 和 HAML 和CoffeeScript
2011-11-07 07:52 12913Asset Pipeline 提供了内建 ... -
Invalid gemspec because of the date format in specification
2011-11-07 02:14 2082又是这个date format的错误。 上次出错忘了,记录下 ...
相关推荐
本文将介绍浅谈Ruby on Rails中的include和extend。include主要用来将一个模块插入到一个类或者其它模块。extend用来在一个对象中引入一个模块,这个类从而也具备了这个模块的方法。
主要介绍了Ruby中require、load、include、extend的区别介绍,require、load用于文件,如.rb等等结尾的文件,include、load则用于包含一个文件中的模块,需要的朋友可以参考下
Ruby 1.9+用法 只需使用您希望其实现对象定义的任何方法创建一个模块module RemoteControl # turns the device on def on end # turns the device off def off endend然后在您的类中使用implements方法(也别名为...
module 中的method 又可分为 instance method 和 module method, 当一个 module 被 include 进一个 class ,那么 module 中的 method (注:没有被 module_function 标记的 method)就是 class 中的 instance method, ...
这就是为什么您必须创建一个类并使用Comparateur include或extend它并根据需要使用它。 此实现还允许您构建自己的缓存系统。 安装 将此行添加到应用程序的 Gemfile 中: gem 'comparateur' 然后执行: $ bundle...
索德 概述 Sord是和跨界车。 通过查看YARD文档注释中指定...识别mixin( include和extend ) 支持通用类型,例如Array和Hash 可以推断命名空间的类( [Bar]可以成为GemName::Foo::Bar ) 处理可以为nil返回类型( T
the help of two fully functional case studies that include Apache Struts and Ruby on Rails applications, respectively. Chapter 12: Sculpting Interactive Business Intelligence Interfaces Business ...
MicroEvent.rb 是一个事件发射器库,它为 Ruby 对象提供观察者模式。 它的灵感来自 ,用不到。 设置 添加到您的Gemfile gem 'microevent' 或将复制到您的项目中。 如何使用它 假设您有一个类Klass ,并且您希望...
The pitfalls in this chapter include using the wrong data type for a given problem, using too much swap space, and using inefficient backup strategies. Chapter 7, Security Techniques (Guard Your Data...
It is important to know how to extend the power of jQuery with custom methods as it is a fundamental skill for a top jQuery developer. Chapter 13 introduces the jQuery Deferred Object, which was ...
通过使用钩子方法,可以让我们在Ruby的类或模块的生命周期中进行干预,可以极大的提高编程的灵活性。 与生命周期相关的钩子方法有下面这些: 类与模块相关 Class#inherited Module#include Module#prepended ...
类分析器 用于Ruby类的简单性能分析器。 只需将其包含在您的类的底部,然后让它分析您... include ClassProfiler #include it just before closing the class end 或者,如果您想要更可配置的内容,以仅测量特定的方法
In addition to the above, some advantages of Julia over comparable systems include: Free and open source (MIT licensed) User-defined types are as fast and compact as built-ins No need to vectorize ...
# The DSL is available in this class end 发展历程 建立 bundler install 运行测试 bundler exec rake 运行示例 ruby -I lib examples/{your favorite example}.rb 产生文件 bundle exec rake doc 产品特点 异步...
描述 另一个 slugging gem,使用自定义映射选项将字符串转换为 slug。 安装 gem install slugity ... require 'slugity/extend_string' "one + two = three" . to_slug # => "one-plus-two-equals-three" 还
Refile :: Mongoid 于扩展名。 安装 将此行添加到您的应用程序的Gemfile中: gem 'refile-mongoid' 用法 require "refile/mongoid" ... extend Refile :: Mongoid :: Attachment attachment :profile_image end 执照
使用模块重构 目标 识别表明需要重构的“代码气味”。 使用模块重构多余的代码。 概述 在本实验中,我们有一个Artist类和一个Song类。... 然后,我们将使用extend和include关键字将模块的功能借给Ar
使用模块重构 目标 识别表明需要重构的“代码气味”。 使用模块重构多余的代码。 概述 在本实验中,我们有一个Artist类和一个Song类。...然后,我们将使用extend和include关键字将模块的功能借给Artist和Song