Skip to content

Commit 1facca8

Browse files
DeathKingDeathKing
authored andcommitted
init commit.
0 parents  commit 1facca8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+5453
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Ruby中的元编程
2+
3+
## 简介
4+
5+
  本系列翻译自[Ruby Metaprogramming](http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_1.html)站点上的课程笔记,并加入了我([DeathKing](https://github.com/DeathKing))的一些个人演绎、资料补充等。希望对大家有所帮助。
6+
7+
  该课程由[Satoshi Asakawa](http://www.workingwithrails.com/people/153056-satoshi)讲授,使用ruby 1.9.1p243 [i386-mingw32]。而我的测试环境则是ruby 1.9.2p180 [i386-mingw32]
8+
9+
  本系列教程在2011年9月间翻译完毕,最初发布在我的博客上。于2014年5月间,藉由GitBook整理,并发布在GitHub上。在此期间,Paolo Perrotta所著的《Ruby元编程》也被翻译并出版。同时,Ruby版本也从1.9飞跃到了2.1,尽管如此,本系列介绍的Ruby元编程技术仍然可用,读者可以放心阅读。
10+
11+
## 翻译的动机
12+
13+
  Ruby是动态的、魔幻而有趣的。而元编程(Metaprogramming)技术在Ruby中的应用也让我大开眼界,虽然以前也有浅显地介绍反射机制(Reflection),但我仍然觉得才疏学浅,不能让大家完全感受到元编程的优美。借此机会,我想借Satoshi Asakawa的本系列讲座,为大家展示一个绚丽的Ruby元编程世界。

chapter01.html

Lines changed: 327 additions & 0 deletions
Large diffs are not rendered by default.

chapter02.html

Lines changed: 407 additions & 0 deletions
Large diffs are not rendered by default.

chapter03.html

Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
<!DOCTYPE HTML>
2+
<html lang="en-US" manifest="./manifest.appcache">
3+
4+
<head prefix="og: http://ogp.me/ns# book: http://ogp.me/ns/book#">
5+
6+
7+
<meta charset="UTF-8">
8+
<title>方法的调用 | Ruby中的元编程</title>
9+
10+
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
11+
<meta name="robots" content="index, follow">
12+
<meta name="author" content="">
13+
<meta name="description" content="  本系列翻译自Ruby Metaprogramming站点上的课程笔记,并加入了我(DeathKing)的一些个人演绎、资料补充等。希望对大家有所帮助。">
14+
<meta name="keywords" content="gitbook,github" >
15+
<meta name="generator" content="www.gitbook.io">
16+
17+
18+
<link rel="next" href="./chapter04.html" />
19+
20+
21+
<link rel="prev" href="./chapter02.html" />
22+
23+
24+
<meta property="og:title" content="方法的调用 | Ruby中的元编程">
25+
<meta property="og:site_name" content="Ruby中的元编程">
26+
<meta property="og:type" content="book">
27+
<meta property="og:locale" content="en_US">
28+
29+
<meta property="book:author" content="https://github.com/">
30+
<meta property="book:tag" content="GitBook">
31+
32+
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
33+
<meta name="apple-mobile-web-app-capable" content="yes">
34+
<meta name="apple-mobile-web-app-status-bar-style" content="black">
35+
36+
<link rel="shortcut icon" href="gitbook/images/favicon.ico" type="image/x-icon">
37+
38+
39+
</head>
40+
<body>
41+
42+
43+
44+
<link rel="stylesheet" href="gitbook/style.css">
45+
46+
47+
48+
49+
<div class="book" data-level="3" data-basepath="." data-revision="1401444078312">
50+
<div class="book-header">
51+
<!-- Actions Left -->
52+
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
53+
54+
<a href="https://github.com/null" target="_blank" class="btn pull-left home-bookmark" aria-label="GitHub home"><i class="fa fa-bookmark-o"></i></a>
55+
56+
<a href="#" class="btn pull-left toggle-search" aria-label="Toggle search"><i class="fa fa-search"></i></a>
57+
<span id="font-settings-wrapper">
58+
<a href="#" class="btn pull-left toggle-font-settings" aria-label="Toggle font settings"><i class="fa fa-font"></i>
59+
</a>
60+
<div class="dropdown-menu font-settings">
61+
<div class="dropdown-caret">
62+
<span class="caret-outer"></span>
63+
<span class="caret-inner"></span>
64+
</div>
65+
66+
<div class="btn-group btn-block">
67+
<button id="reduce-font-size" class="btn btn-default">A</button>
68+
<button id="enlarge-font-size" class="btn btn-default">A</button>
69+
</div>
70+
71+
<ul class="list-group font-family-list">
72+
<li class="list-group-item" data-font="0">Serif</li>
73+
<li class="list-group-item" data-font="1">Sans</li>
74+
</ul>
75+
76+
<div class="btn-group btn-group-xs btn-block color-theme-list">
77+
<button type="button" class="btn btn-default" id="color-theme-preview-0" data-theme="0">White</button>
78+
<button type="button" class="btn btn-default" id="color-theme-preview-1" data-theme="1">Sepia</button>
79+
<button type="button" class="btn btn-default" id="color-theme-preview-2" data-theme="2">Night</button>
80+
</div>
81+
</div>
82+
83+
</span>
84+
85+
<!-- Actions Right -->
86+
87+
<a href="#" target="_blank" class="btn pull-right google-plus-sharing-link sharing-link" data-sharing="google-plus" aria-label="Share on Google Plus"><i class="fa fa-google-plus"></i></a>
88+
89+
90+
<a href="#" target="_blank" class="btn pull-right facebook-sharing-link sharing-link" data-sharing="facebook" aria-label="Share on Facebook"><i class="fa fa-facebook"></i></a>
91+
92+
93+
<a href="#" target="_blank" class="btn pull-right twitter-sharing-link sharing-link" data-sharing="twitter" aria-label="Share on Twitter"><i class="fa fa-twitter"></i></a>
94+
95+
96+
97+
98+
<!-- Title -->
99+
<h1>
100+
<i class="fa fa-spinner fa-spin"></i>
101+
<a href="./" >Ruby中的元编程</a>
102+
</h1>
103+
</div>
104+
105+
106+
107+
<div class="book-summary">
108+
<div class="book-search">
109+
<input type="text" placeholder="Search" class="form-control" />
110+
</div>
111+
<ul class="summary">
112+
113+
114+
115+
116+
117+
118+
119+
120+
121+
<li data-level="0" data-path="index.html">
122+
<a href="./"><i class="fa fa-check"></i> Introduction</a>
123+
</li>
124+
125+
126+
<li class="chapter " data-level="1" data-path="chapter01.html">
127+
128+
<a href="./chapter01.html">
129+
<i class="fa fa-check"></i> <b>1.</b> 前言
130+
</a>
131+
132+
133+
</li>
134+
135+
<li class="chapter " data-level="2" data-path="chapter02.html">
136+
137+
<a href="./chapter02.html">
138+
<i class="fa fa-check"></i> <b>2.</b> 实例变量、方法、类
139+
</a>
140+
141+
142+
</li>
143+
144+
<li class="chapter " data-level="3" data-path="chapter03.html">
145+
146+
<a href="./chapter03.html">
147+
<i class="fa fa-check"></i> <b>3.</b> 方法的调用
148+
</a>
149+
150+
151+
</li>
152+
153+
<li class="chapter " data-level="4" data-path="chapter04.html">
154+
155+
<a href="./chapter04.html">
156+
<i class="fa fa-check"></i> <b>4.</b> 实用元编程方法
157+
</a>
158+
159+
160+
</li>
161+
162+
<li class="chapter " data-level="5" data-path="chapter05.html">
163+
164+
<a href="./chapter05.html">
165+
<i class="fa fa-check"></i> <b>5.</b> 绑定
166+
</a>
167+
168+
169+
</li>
170+
171+
<li class="chapter " data-level="6" data-path="chapter06.html">
172+
173+
<a href="./chapter06.html">
174+
<i class="fa fa-check"></i> <b>6.</b> 块和绑定
175+
</a>
176+
177+
178+
</li>
179+
180+
<li class="chapter " data-level="7" data-path="chapter07.html">
181+
182+
<a href="./chapter07.html">
183+
<i class="fa fa-check"></i> <b>7.</b> 元编程实战
184+
</a>
185+
186+
187+
</li>
188+
189+
<li class="chapter " data-level="8" data-path="chapter08.html">
190+
191+
<a href="./chapter08.html">
192+
<i class="fa fa-check"></i> <b>8.</b> 结语
193+
</a>
194+
195+
196+
</li>
197+
198+
199+
200+
201+
<li class="divider"></li>
202+
<li>
203+
<a href="http://www.gitbook.io/" target="blank" class="gitbook-link">Generated using GitBook</a>
204+
</li>
205+
206+
</ul>
207+
</div>
208+
209+
<div class="book-body">
210+
<div class="body-inner">
211+
<div class="page-wrapper" tabindex="-1">
212+
<div class="book-progress">
213+
<div class="bar">
214+
<div class="inner" style="width: 37.5%;min-width: 25%;"></div>
215+
</div>
216+
<div class="chapters">
217+
218+
<a href="./index.html" title="Introduction" class="chapter done new-chapter" data-progress="0" style="left: 0%;"></a>
219+
220+
<a href="./chapter01.html" title="前言" class="chapter done new-chapter" data-progress="1" style="left: 12.5%;"></a>
221+
222+
<a href="./chapter02.html" title="实例变量、方法、类" class="chapter done new-chapter" data-progress="2" style="left: 25%;"></a>
223+
224+
<a href="./chapter03.html" title="方法的调用" class="chapter done new-chapter" data-progress="3" style="left: 37.5%;"></a>
225+
226+
<a href="./chapter04.html" title="实用元编程方法" class="chapter new-chapter" data-progress="4" style="left: 50%;"></a>
227+
228+
<a href="./chapter05.html" title="绑定" class="chapter new-chapter" data-progress="5" style="left: 62.5%;"></a>
229+
230+
<a href="./chapter06.html" title="块和绑定" class="chapter new-chapter" data-progress="6" style="left: 75%;"></a>
231+
232+
<a href="./chapter07.html" title="元编程实战" class="chapter new-chapter" data-progress="7" style="left: 87.5%;"></a>
233+
234+
<a href="./chapter08.html" title="结语" class="chapter new-chapter" data-progress="8" style="left: 100%;"></a>
235+
236+
</div>
237+
</div>
238+
239+
<div class="page-inner">
240+
241+
<section class="normal" id="section-gitbook_7">
242+
243+
<h1 id="-">方法的调用</h1>
244+
<p>  当你在调用某一个方法的时候,Ruby会完成下面的步骤:</p>
245+
<ul>
246+
<li>找到这个方法,我们把这个过程称作<strong>方法查找(method lookup)</strong></li>
247+
<li>执行这个方法,为了执行这个方法,Ruby需要一个叫做<code>self</code>的伪变量;</li>
248+
</ul>
249+
<h2 id="-">方法的查找</h2>
250+
<p>  要理解Ruby的方法查找,你需要了解下面两个概念:<strong>接受者(receiver)</strong><strong>祖先链(ancestors chain)</strong>。接受者就是方法的调用者。例如,对调用<code>an_object.display()</code>来说,<code>an_object</code>就是接受者。而关于祖先链,请考察任何一个Ruby类的内部。想象一下从一个类移动到其父类,然后再移动到父类的父类,直到到达<code>Object</code>类(默认的父类),然后继续移动,最终到达<code>BasicObject</code>类(Ruby层级模型中的根)。你遍历这些类所走过的路径就是“祖先链”(祖先链中也包括模块)。</p>
251+
<p>  因此,为了查找方法,Ruby首先进入receiver所属的类,并以此为起始,沿着祖先链不断前进,直到找到目标方法。这种行为也被称作<strong>“向右一步,再向上(one step to the right, then up)”</strong>规则:向右一步,进入reciver所属的类,然后再向上查找祖先链,直到找到目标方法。(译者注:如果遍历完祖先链也没有找到方法的话,会调用<code>method_missing</code>方法,如果这个方法没有被定义,则抛出<code>NoMethodError</code>)当你在一个类中包含一个模块时,Ruby创建了一个匿名类来封装这个模块,并将这个匿名类插入到祖先链中,也在这个类的上方。</p>
252+
<p>  下面的代码演示了一次方法查找:</p>
253+
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span></span>
254+
<span class="hljs-function"><span class="hljs-keyword">def</span> </span>foo
255+
<span class="hljs-keyword">end</span>
256+
<span class="hljs-keyword">end</span>
257+
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">B</span> <span class="hljs-inheritance">&lt; <span class="hljs-parent">A</span></span></span>
258+
<span class="hljs-function"><span class="hljs-keyword">def</span> </span>bar
259+
<span class="hljs-comment"># bar method in B</span>
260+
<span class="hljs-keyword">end</span>
261+
<span class="hljs-keyword">end</span>
262+
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">C</span> <span class="hljs-inheritance">&lt; <span class="hljs-parent">B</span></span></span>
263+
<span class="hljs-function"><span class="hljs-keyword">def</span> </span>bar
264+
<span class="hljs-comment"># bar method in C</span>
265+
<span class="hljs-comment"># overwriting superclass' method</span>
266+
<span class="hljs-keyword">end</span>
267+
<span class="hljs-keyword">end</span>
268+
269+
obj = <span class="hljs-constant">C</span>.new
270+
obj.bar <span class="hljs-comment">#=&gt; in C class</span>
271+
obj.foo <span class="hljs-comment">#=&gt; not in C class</span>
272+
<span class="hljs-comment">#=&gt; then go to C's superclass B</span>
273+
<span class="hljs-comment">#=&gt; not in B class</span>
274+
<span class="hljs-comment">#=&gt; then go to B's superclass A</span>
275+
<span class="hljs-comment">#=&gt; execute it</span>
276+
</code></pre>
277+
<h2 id="self">self</h2>
278+
<ul>
279+
<li>在Ruby中,<code>self</code>是一个很特殊的变量,它总是指向当前对象(current object);</li>
280+
<li><code>self</code>被认为是默认的receiver。也就是说,你如果没有明确指出receiver,那么系统将把<code>self</code>当做receiver;</li>
281+
<li>实例变量是在<code>self</code>(当前对象)中查找的。也就是说,如果我使用<code>@var</code>,那么Ruby就会在<code>self</code>所指向的对象中去寻找此实例变量。需要注意的是,实例变量并不是由类定义的,它们也和子类以及继承机制无关。</li>
282+
</ul>
283+
<p>  因此,当我们在调用一个明确指出receiver的方法时,Ruby会按照下面的步骤执行:</p>
284+
<pre><code class="lang-ruby">obj.do_method(param)
285+
</code></pre>
286+
<ul>
287+
<li><code>self</code>指向<code>obj</code></li>
288+
<li><code>self</code>所属的类中查找<code>do_method(param)</code>方法(方法是存放在类中,而不是实例中!);</li>
289+
<li>调用方法<code>do_method(param)</code></li>
290+
</ul>
291+
292+
293+
</section>
294+
295+
</div>
296+
</div>
297+
</div>
298+
299+
300+
<a href="./chapter02.html" class="navigation navigation-prev " aria-label="Previous page: 实例变量、方法、类"><i class="fa fa-angle-left"></i></a>
301+
302+
303+
<a href="./chapter04.html" class="navigation navigation-next " aria-label="Next page: 实用元编程方法"><i class="fa fa-angle-right"></i></a>
304+
305+
</div>
306+
</div>
307+
308+
309+
310+
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js"></script>
311+
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/mode-javascript.js"></script>
312+
<script src="gitbook/jsrepl/jsrepl.js" id="jsrepl-script"></script>
313+
<script src="gitbook/app.js"></script>
314+
315+
316+
317+
<script src="gitbook/plugins/gitbook-plugin-mixpanel/plugin.js"></script>
318+
319+
320+
321+
<script src="http://cdn.mathjax.org/mathjax/2.0-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
322+
323+
324+
325+
<script src="gitbook/plugins/gitbook-plugin-mathjax/plugin.js"></script>
326+
327+
328+
<script>
329+
require(["gitbook"], function(gitbook) {
330+
var config = {};
331+
gitbook.start(config);
332+
});
333+
</script>
334+
335+
336+
</body>
337+
338+
</html>

0 commit comments

Comments
 (0)