- 浏览: 849241 次
- 性别:
- 来自: lanzhou
文章分类
最新评论
-
liu346435400:
楼主讲了实话啊,中国程序员的现状,也是只见中国程序员拼死拼活的 ...
中国的程序员为什么这么辛苦 -
qw8226718:
国内ASP.NET下功能比较完善,优化比较好的Spacebui ...
国内外开源sns源码大全 -
dotjar:
敢问兰州的大哥,Prism 现在在12.04LTS上可用么?我 ...
最佳 Ubuntu 下 WebQQ 聊天体验 -
coralsea:
兄弟,卫星通信不是这么简单的,单向接收卫星广播信号不需要太大的 ...
Google 上网 -
txin0814:
我成功安装chrome frame后 在IE地址栏前加上cf: ...
IE中使用Google Chrome Frame运行HTML 5
After writing my last post on Rails plugin idioms, I realized that Ruby metaprogramming, at its core, is actually quite simple.
It comes down to the fact that all Ruby code is executed code–there
is no separate compile or runtime phase. In Ruby, every line of code is
executed against a particular self
. Consider the following five snippets:
class Person def self .species "Homo Sapien" end end class Person class << self def species "Homo Sapien" end end end class << Person def species "Homo Sapien" end end Person.instance_eval do def species "Homo Sapien" end end def Person.species "Homo Sapien" end
All five of these snippets define a Person.species
that returns Homo Sapien
. Now consider another set of snippets:
class Person def name "Matz" end end Person.class_eval do def name "Matz" end end
These snippets all define a method called name
on the Person class. So Person.new.name
will return “Matz”. For those familiar with Ruby, this isn’t news. When
learning about metaprogramming, each of these snippets is presented in
isolation: another mechanism for getting methods where they “belong”.
In fact, however, there is a single unified reason that all of these
snippets work the way they do.
First, it is important to understand how Ruby’s metaclass works. When you first learn Ruby, you learn about the concept of the class, and that each object in Ruby has one:
class Person end Person.class #=> Class class Class def loud_name "#{name.upcase}!" end end Person.loud_name #=> "PERSON!"
Person
is an instance of Class
, so any methods added to Class
are available on Person
as well. What they don’t tell you, however, is that each object in Ruby also has its own metaclass
, a Class
that can have methods, but is only attached to the object itself.
matz = Object .new def matz.speak "Place your burden to machine's shoulders" end
What’s going on here is that we’re adding the speak
method to matz
’s metaclass
, and the matz
object inherits from its metaclass
and then Object
. The reason this is somewhat less clear than ideal is that the metaclass is invisible in Ruby:
matz = Object .new def matz.speak "Place your burden to machine's shoulders" end matz.class #=> Object
In fact, matz
’s “class” is its invisible metaclass. We can even get access to the metaclass:
metaclass = class << matz; self ; end metaclass.instance_methods .grep ( / speak/ ) #=> ["speak"]
At this point in other articles on this topic, you’re probably
struggling to keep all of the details in your head; it seems as though
there are so many rules. And what’s this class << matz
thing anyway?
It turns out that all of these weird rules collapse down into a single concept: control over the self
in a given part of the code. Let’s go back and take a look at some of the snippets we looked at earlier:
class Person def name "Matz" end self .name #=> "Person" end
Here, we are adding the name
method to the Person
class. Once we say class Person
, the self
until the end of the block is the Person
class itself.
Person.class_eval do def name "Matz" end self .name #=> "Person" end
Here, we’re doing exactly the same thing: adding the name
method to instances of the Person class. In this case, class_eval
is setting the self
to Person
until the end of the block. This is all perfectly straight forward when
dealing with classes, but it’s equally straight forward when dealing
with metaclasses:
def Person.species "Homo Sapien" end Person.name #=> "Person"
As in the matz
example earlier, we are defining the species
method on Person
’s metaclass. We have not manipulated self
, but you can see using def
with an object attaches the method to the object’s metaclass.
class Person def self .species "Homo Sapien" end self .name #=> "Person" end
Here, we have opened the Person
class, setting the self
to Person
for the duration of the block, as in the example above. However, we are defining a method on Person
’s metaclass here, since we’re defining the method on an object (self
). Also, you can see that self.name
while inside the person class is identical to Person.name
while outside it.
class << Person def species "Homo Sapien" end self .name #=> "" end
Ruby provides a syntax for accessing an object’s metaclass directly. By doing class << Person
, we are setting self
to Person
’s metaclass for the duration of the block. As a result, the species
method is added to Person
’s metaclass, rather than the class itself.
class Person class << self def species "Homo Sapien" end self .name #=> "" end end
Here, we combine several of the techniques. First, we open Person
, making self
equal to the Person
class. Next, we do class << self
, making self
equal to Person
’s metaclass. When we then define the species
method, it is defined on Person
’s metaclass.
Person.instance_eval do def species "Homo Sapien" end self .name #=> "Person" end
The last case, instance_eval
, actually does something interesting. It breaks apart the self
into the self
that is used to execute methods and the self
that is used when new methods are defined. When instance_eval
is used, new methods are defined on the metaclass
, but the self
is the object itself.
In some of these cases, the multiple ways to achieve the same thing
arise naturally out of Ruby’s semantics. After this explanation, it
should be clear that def Person.species
, class << Person; def species
, and class Person; class << self; def species
aren’t three ways to achieve the same thing by design
, but that they arise out of Ruby’s flexibility with regard to specifying what self
is at any given point in your program.
On the other hand, class_eval
is slightly different.
Because it take a block, rather than act as a keyword, it captures the
local variables surrounding it. This can provide powerful DSL
capabilities, in addition to controlling the self
used in a code block. But other than that, they are exactly identical to the other constructs used here.
Finally, instance_eval
breaks apart the self
into two parts, while also giving you access to local variables defined outside of it.
In the following table, defines a new scope means that code inside the block does not have access to local variables outside of the block.
Person | same | yes |
Person’s metaclass | same | yes |
Person | same | no |
Person | Person’s metaclass | no |
Also note that class_eval
is only available to Modules
(note that Class inherits from Module) and is an alias for module_eval
. Additionally, instance_exec
, which was added to Ruby in 1.8.7, works exactly like instance_eval
, except that it also allows you to send variables into the block.
UPDATE:
Thank you to Yugui of the Ruby core team for correcting the original post
, which ignored the fact that self
is broken into two in the case of instance_eval
.
发表评论
-
Ruby 1.8 and 1.9 living in harmony
2010-02-22 07:54 888I’m running on OSX, and using M ... -
Perl vs. Python vs. Ruby
2009-11-07 21:05 1158I’m evaluating Python and Rub ... -
A Teenage Boy Improved Ruby 1.9 Performance Up to 63%
2009-11-06 18:26 903Japanese online magazine, @IT J ... -
Ruby Best Practices - The Complete Class
2009-11-04 16:21 1045A remark: we enabled comment mo ... -
调查显示Ruby北美地区用户量上升
2009-10-30 07:38 584据Evans Data最近针对400名开发用户的调查表明,R ... -
RubyForge将停止工作,RubyGems.org接替Gem hosting服务
2009-10-28 14:14 1845Ruby Gem维护者请注意,数周前,GitHubGitHub ... -
有关Ruby企业版1.8.7的一些介绍
2009-10-18 08:54 1304前几周,Ruby企业版(Rub ... -
3 Ruby Quirks You Have to Love
2009-10-16 10:50 658Ruby’s a fantastic language; we ... -
Distilling JRuby: The JIT Compiler
2009-10-09 08:40 1143The JIT compiler in JRuby is a ... -
Compiling Ruby with MacRuby 0.5b1
2009-10-09 08:33 1276MacRuby 0.5b1 and can be downlo ... -
10月编程语言排行榜:Ruby稳步提升
2009-10-08 08:07 1011新闻来源:51CTO.COMTIOBE今日公布了2009年10 ... -
为你的.NET应用程序添加一个REPL控制台
2009-10-07 12:45 783微软开始推广IronPython和IronRuby,希望它们可 ... -
Installing Ruby 1.8 and 1.9 on Ubuntu from Source
2009-10-05 14:18 920$ sudo apt-get build-dep ru ... -
Compiling Ruby 1.9.1 (stable) on Ubuntu
2009-10-05 14:13 760I found the default ruby inst ... -
JRuby综述:1.4的新特性、JRubyConf议程及MLVM
2009-10-02 08:25 888JRuby 1.4 RC1即将发布,我们来看看新版本都有哪些新 ... -
Ruby Enterprise Edition 1.8.7-20090928 released
2009-09-30 08:09 1180In the not so distant past we l ... -
Ruby DCamp,低迷经济下别开生面的会议
2009-09-22 08:47 999经济的低迷不仅影响了 ... -
Ruby静态分析工具检视:metric_fu, Simian, Saikuro以及其他
2009-09-17 08:59 1492代码质量构成了软件质 ... -
Ruby 1.9.1程序库兼容性纵览
2009-09-15 09:38 1145ruby.1.9.1是1.9.x系列第一 ... -
ruby 1.9 真有这么快吗?
2009-09-14 18:26 1192早在今年2月份,Antonio Cangiano 发表过一份关 ...
相关推荐
《Metaprogramming Ruby: Programming Like the Ruby Pros》是一本深入探讨Ruby元编程技术的专业书籍,作者Paolo Perrotta通过丰富的实例和清晰的概念解析,帮助读者理解和掌握Ruby中的高级编程技巧。本书不仅适用于...
MetaProgramming in Ruby系列教程的中译版。 uby是动态的、魔幻而有趣的。而元编程(Metaprogramming)技术在Ruby中的应用也让我大开眼界,虽然以前也有浅显地介绍反射机制(Reflection),但我仍然觉得才疏学浅,不...
这本《Metaprogramming Ruby》书籍深入探讨了如何利用Ruby的特性进行元编程,帮助开发者提升代码的灵活性、可扩展性和复用性。源代码提供了书中各个示例的实践,让读者能够更好地理解元编程的概念。 元编程的核心...
Dig under the surface and explore Ruby's most advanced feature: a collection of techniques and tricks known as metaprogramming. In this book, you'll learn metaprogramming as an essential component of ...
Pragmatic.Metaprogramming.Ruby.Feb.2010.rar
### Metaprogramming Ruby 2nd Edition:深入理解Ruby元编程 #### 一、书籍简介与价值 《Metaprogramming Ruby 2nd Edition》是一本深入探讨Ruby语言元编程特性的经典之作。本书不仅适合那些希望深入了解Ruby内部...
### Metaprogramming Ruby:深入理解动态编程的力量 #### 标题解读 “Metaprogramming Ruby”这一标题明确地指出了本书的核心内容——通过元编程技术深入探索Ruby语言的独特魅力。元编程(Metaprogramming)是一种...
The gain for the reader is that TMP is presented in the book as a set of techniques that will enable a new style to your C++ coding while making it exceptionally clear and efficient. The book deals ...
### Metaprogramming in .NET #### 知识点概览 - **元编程概念**:定义、目的、实现方式。 - **反射技术**:基本原理、应用领域、操作示例。 - **文本模板转换工具包 (T4)**:工作流程、应用场景、模板语法介绍。 -...
C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond By David Abrahams, Aleksey Gurtovoy Publisher : Addison Wesley Professional Pub Date : December 10, 2004 ISBN ...
express algorithms in a very natural way, and then it’s just a matter of typing ruby at the command line and pressing enter, and your Ruby script is running. However, Ruby’s syntax is deceptively ...
《Metaprogramming Ruby》是一本专注于Ruby编程语言元编程技术的书籍,由Paolo Perrotta撰写。元编程是一种编程范式,它允许在程序运行时修改或创建程序结构和行为。在Ruby中,元编程是其核心特性之一,使得代码能够...
第 10 周:创客学院在 Ruby 中玩转元编程挑战: 使用method_missing重新定义对象在询问has_unknown_attribute时的Reacthas_unknown_attribute 。 使用define_method创建Ruby 内置attr_accessor方法的布尔版本。代码...
Ruby 元编程演示 由 Leigh Halliday 创建 例子 在示例文件夹中找到。 查看演示文稿的说明 安装 安装 克隆reveal.js 存储库 $ git clone https://github.com/leighhalliday/ruby-dsl-workshop.git 导航到reveal.js...
The classic C++ language admits two basic types of templates—function templates and class templates2: Here is a function template: template scalar_t sq(const scalar_t& x) { return x*x; } Here is a ...
《Metaprogramming Ruby(Second Edition)》是Ruby编程语言领域的一本经典著作,由Peter Eberhardt和Paolo Perrotta共同撰写。这本书详细介绍了如何利用Ruby的强大元编程特性来提升代码的灵活性、可扩展性和简洁性。...
.NET框架是微软开发的一种软件开发平台,它提供了丰富的类库和...在《Metaprogramming in .NET》这本书中,作者深入探讨了这些主题,旨在帮助开发者充分利用.NET框架的元编程能力,打造更高效、更灵活的软件解决方案。
Metaprogramming Ruby 2nd Edition – FreePdfBook