OSDN Git Service

syntaxは文法よりも構文のほうがより適切であるため、修正.
[omake-japanese/omake_trans.git] / detail.rst
1 .. 6-detail
2
3 .. index::
4    single: osh(1)
5    single: value
6 .. _label6:
7
8 6. 式と値
9 ==================================
10 .. omake provides a full programming-language including many system and IO functions. The language is object-oriented – everything is an object, including the base values like numbers and strings. However, the omake language differs from other scripting languages in three main respects.
11
12       * Scoping is dynamic.
13       * Apart from IO, the language is entirely functional – there is no assignment operator in the language.
14       * Evaluation is normally eager – that is, expressions are evaluated as soon as they are encountered. 
15
16 omakeは多くのシステムとIO関数を含んでいる、フル機能のプログラミング言語です。この言語はオブジェクト指向言語であり、数値や文字列のような基本の型もすべてオブジェクトで表現されます。しかしながら、このomake言語は3つの点において、他のスクリプト言語とは異なっています。
17
18 * 動的なスコーピングを行います。
19 * IOを除いて、この言語は全体が関数的です。この言語は代入という操作が存在しません。
20 * 値の評価は通常の場合その場で行われます。これは、式が表れた瞬間に評価されるということを意味しています。
21
22 .. To illustrate these features, we will use the osh(1) omake program shell. The osh(1) program provides a toploop, where expressions can be entered and the result printed. osh(1) normally interprets input as command text to be executed by the shell, so in many cases we will use the value form to evaluate an expression directly.
23
24 これらの機能を確かめるため、今回私たちは ``osh(1)`` omakeプログラムを使いました。 ``osh(1)`` プログラムは式を入力したら、すぐに結果が出力されるインタープリターとなっています。 ``osh(1)`` は通常シェル上で実行するために、入力された文章をコマンド文として解釈しますので、式を直接評価するためには多くの場合 ``value`` 文を使用します。 ::
25
26     osh> 1
27     *** omake error: File -: line 1, characters 0-1 command not found: 1
28     osh> value 1
29     - : "1" : Sequence
30     osh> ls -l omake
31     -rwxrwxr-x  1 jyh jyh 1662189 Aug 25 10:24 omake*
32
33 .. index::
34    single: 動的なスコーピング
35    single: CC
36    single: CFLAGS
37    single: private
38 .. _label6.1:
39
40 6.1 動的なスコーピング
41 ----------------------------------
42 .. Dynamic scoping means that the value of a variable is determined by the most recent binding of the variable in scope at runtime. Consider the following program.
43
44 動的なスコーピングは言い換えると、変数の値が実行されているスコープ中で、もっとも近くで束縛されている変数によって決定されることを意味しています。以下のプログラムについて考えて見ましょう。 ::
45
46     OPTIONS = a b c
47     f() =
48        println(OPTIONS = $(OPTIONS))
49     g() =
50        OPTIONS = d e f
51        f()
52
53 .. If f() is called without redefining the OPTIONS variable, the function should print the string OPTIONS = a b c.
54
55 ``f()`` が ``OPTIONS`` 変数を再定義することなく呼び出した場合、この関数は文字列 ``OPTIONS = a b c`` が出力されます。
56
57 .. In contrast, the function g() redefines the OPTIONS variable and evaluates f() in that scope, which now prints the string OPTIONS = d e f.
58
59 対照的に、関数 ``g()`` は ``OPTIONS`` 変数を再定義し、 ``f()`` をそのスコープ中で評価しますので、 この関数は文字列 ``OPTIONS = d e f`` が出力されます。
60
61 .. The body of g defines a local scope – the redefinition of the OPTIONS variable is local to g and does not persist after the function terminates.
62
63 ``g`` の内容はローカルスコープを定義しています。 ``OPTIONS`` 変数の再定義は ``g`` についてローカルであり、この関数が終了した場合、この定義も終了します。 ::
64
65     osh> g()
66     OPTIONS = d e f
67     osh> f()
68     OPTIONS = a b c
69
70 .. Dynamic scoping can be tremendously helpful for simplifying the code in a project. For example, the OMakeroot file defines a set of functions and rules for building projects using such variables as CC, CFLAGS, etc. However, different parts of a project may need different values for these variables. For example, we may have a subdirectory called opt where we want to use the -03 option, and a subdirectory called debug where we want to use the -g option. Dynamic scoping allows us to redefine these variables in the parts of the project without having to redefine the functions that use them.
71
72 動的なスコーピングはプロジェクトでのコードを簡略化するための非常に有用なツールです。例えば、 ``OMakeroot`` ファイルでは関数の集合、 ``CC`` や ``CFLAGS`` などの変数を使ったプロジェクトのビルドルールについて定義しています。しかしながら、プロジェクト中の異なったパートでは、これらの変数がそれぞれ異なった値であってほしいと思うことがあるでしょう。例えば、サブディレクトリ ``opt`` では、私たちは ``-O3`` オプションを、サブディレクトリ ``debug`` では ``-g`` オプションを用いてビルドしたいものとします。この問題は動的なスコーピングを用いて、関数を再定義することなく、プロジェクト中の一部の変数を置き換えることができます。 ::
73
74     section
75        CFLAGS = -O3
76        .SUBDIRS: opt
77     section
78        CFLAGS = -g
79        .SUBDIRS: debug
80
81 .. However, dynamic scoping also has drawbacks. First, it can become confusing: you might have a variable that is intended to be private, but it is accidentally redefined elsewhere. For example, you might have the following code to construct search paths.
82
83 しかしながら、動的なスコーピングは欠点も持っています。はじめに、この機能は分かりずらいです。あなたはプライベートにしたい変数があるとします。しかしこれはどこか別の場所で再定義される恐れがあります。例えば、あなたは以下の検索パスを組み立てるコードを持っていたとします。 ::
84
85    PATHSEP = :
86    make-path(dirs) =
87       return $(concat $(PATHSEP), $(dirs))
88
89    make-path(/bin /usr/bin /usr/X11R6/bin)
90    - : "/bin:/usr/bin:/usr/X11R6/bin" : String
91
92 .. However, elsewhere in the project, the PATHSEP variable is redefined as a directory separator /, and your function suddenly returns the string /bin//usr/bin//usr/X11R6/bin, obviously not what you want.
93
94 しかしながら、プロジェクトのどこかで ``PATHSEP`` 変数がディレクトリのセパレータ ``/`` で再定義された場合、この関数は突如文字列 ``/bin//usr/bin//usr/X11R6/bin`` を返すようになります。あなたは明らかにそれを望んでいないのにです。
95
96 .. The private block is used to solve this problem. Variables that are defined in a private block use static scoping – that is, the value of the variable is determined by the most recent definition in scope in the source text.
97
98 ``private`` ブロックはこの問題を解決するために用いられます。 ``private`` ブロック内で定義された変数は静的なスコーピングを用います。これは、変数の値がソーステキストのスコープ中で、もっとも最近の定義によって決定されることを示しています。 ::
99
100    private
101       PATHSEP = :
102    make-path(dirs) =
103       return $(concat $(PATHSEP), $(dirs))
104
105    PATHSEP = /
106    make-path(/bin /usr/bin /usr/X11R6/bin)
107    - : "/bin:/usr/bin:/usr/X11R6/bin" : String
108
109 .. _label6.2:
110
111 6.2 関数評価
112 ----------------------------------
113 .. Apart from I/O, omake programs are entirely functional. This has two parts:
114
115       * There is no assignment operator.
116       * Functions are values, and may be passed as arguments, and returned from functions just like any other value. 
117
118 IOを除いて、omakeのプログラムは全体が関数的です。これは二つの意味を持っています。
119
120 * 代入という操作が存在しません。
121 * 関数は引数を渡して、別の値を返す『値(value)』です。
122
123 .. The second item is straightforward. For example, the following program defines an increment function by returning a function value.
124
125 二番目についてはそのままの説明です。例えば、以下のプログラムでは関数の値を返すことによって加算する関数を定義しています。 ::
126
127    incby(n) =
128       g(i) =
129          return $(add $(i), $(n))
130       return $(g)
131
132    f = $(incby 5)
133
134    value $(f 3)
135    - : 8 : Int
136
137 .. The first item may be the most confusing initially. Without assignment, how is it possible for a subproject to modify the global behavior of the project? In fact, the omission is intentional. Build scripts are much easier to write when there is a guarantee that subprojects do not interfere with one another.
138
139 一番目については恐らく最初は困惑することでしょう。代入なしで、いったいどのようにして、サブプロジェクトにプロジェクトのグローバルな振る舞いを修正することができるのでしょうか?実際、この省略された説明は意図的にされています。サブプロジェクトが他のプロジェクトの邪魔をしないことを保障されているとき、ビルドスクリプトはより書きやすくなります。
140
141 .. However, there are times when a subproject needs to propagate information back to its parent object, or when an inner scope needs to propagate information back to the outer scope.
142
143 しかしながら、サブプロジェクトが親のオブジェクトに情報を伝える必要がある場合や、内部のスコープが外部のスコープに情報を伝える必要がある場合が存在することも確かです。
144
145 .. index::
146    single: export
147    single: .PHONY
148 .. _label6.3:
149
150 6.3 環境のエクスポート
151 ----------------------------------
152 .. The export directive can be used to propagate all or part of an inner scope back to its parent. If used without arguments, the entire scope is propagated back to the parent; otherwise the arguments specify which part of the environment to propagate. The most common usage is to export some or all of the definitions in a conditional block. In the following example, the variable B is bound to 2 after the conditional. The A variable is not redefined.
153
154 ``export`` 文によってすべて、あるいは一部の内部スコープの情報を親スコープに伝えることができます。もし引数が存在しない場合、全体のスコープの情報が親に伝えられます。さもなければ引数の変数のみが伝えられます。もっともよく使うやり方は、条件分岐中のいくつか、あるいはすべての定義をエクスポートする場合です。以下の例では、変数 ``B`` は評価された後に、2に束縛されます。変数 ``A`` は再定義されません。 ::
155
156     if $(test)
157        A = 1
158        B = $(add $(A), 1)
159        export B
160     else
161        B = 2
162        export
163
164 .. If the export directive is used without an argument, all of the following is exported: 
165
166       * The values of all the dynamically scoped variables (as described in Section 5.5).
167       * The current working directory.
168       * The current Unix environment.
169       * The current implicit rules and implicit dependencies (see also Section 8.11.1).
170       * The current set of “phony” target declarations (see Sections 8.10 and 8.11.3). 
171
172 ``export`` 文が引数なしに用いられた場合は、以下のすべてが出力されます。
173
174 * 動的にスコープされたすべての値 (":ref:`label5.5`"で説明しました)
175 * 現在のワーキングディレクトリ
176 * 現在のUNIX環境
177 * 現在の暗黙のルールと暗黙の依存関係 (詳細は ":ref:`label8.11.1`" を参照してください)
178 * 現在の"phony"ターゲット宣言の集合 (詳細は ":ref:`label8.10`",":ref:`label8.11.3`" を参照してください)
179
180 .. If the export directive is used with an argument, the argument expression is evaluated and the resulting value is interpreted as follows:
181       * If the value is empty, everything is exported, as described above.
182       * If the value represents a environment (or a partial environment) captured using the export function, then the corresponding environment or partial environment is exported.
183       * Otherwise, the value must be a sequence of strings specifying which items are to be propagated back. The following strings have special meaning:
184             o .RULE — implicit rules and implicit dependencies.
185             o .PHONY — the set of “phony” target declarations. 
186         All other strings are interpreted as names of the variables that need to be propagated back. 
187
188 ``export`` 文が引数ありで用いられた場合は、引数の式が評価され、返される値は以下のようになります。
189
190 * もし値が空であるなら、上で説明したすべてがエクスポートされます。
191 * もし値が環境(environment)、あるいは部分的な環境を表現しているのなら( 詳細は ":ref:`label9.3.41`" を参照してください)、対象の環境または部分的な環境がエクスポートされます。
192 * そうでなければ、値は出力したい項目を指定している、文字列のシーケンスでなければなりません。また、以下の文字列は特別な意味を持ちます。
193   
194   * ``.RULE`` ー 暗黙のルールと、暗黙的な依存関係
195   * ``.PHONY`` ー "phony"ターゲット宣言の集合
196   
197   すべての他の文字列は、出力する必要のある変数名として解釈されます。
198
199 例えば以下の(わざとらしい)例では、変数 ``A`` と ``B`` がエクスポートされ、さらに暗黙のルールはこのセクションが終わった後も、環境の中で保持されます。しかし、変数 ``TMP`` とターゲット ``tmp_phony`` は変更されずに、このセクションの中にとどまります。 ::
200
201   section
202      A = 1
203      B = 2
204      TMP = $(add $(A), $(B))
205
206      .PHONY: tmp_phony
207
208      tmp_phony:
209         prepare_foo
210
211      %.foo: %.bar tmp_phony
212         compute_foo $(TMP) $< $@
213      export A B .RULE
214
215 .. index::
216    single: export
217 .. _label6.3.1:
218
219 6.3.1 区域のエクスポート
220 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
221 .. This feature was introduced in version 0.9.8.5.
222
223 *この機能はバージョン0.9.8.5で導入されました。*
224
225 .. The export directive does not need to occur at the end of a block. An export is valid from the point where it is specified to the end of the block in which it is contained. In other words, the export is used in the program that follows it. This can be especially useful for reducing the amount of code you have to write. In the following example, the variable CFLAGS is exported from the both branches of the conditional.
226
227 ``export`` 文はブロックの最後で実行する必要はありません。エクスポートはブロック中のブロックも、ブロックの終わりでエクスポートされます。言い換えると、 ``export`` はその文の次にくるプログラムでも用いられます。これはコード量を減らすという点で特に有用です。以下の例では、変数 ``CFLAGS`` は両方の条件分岐文からエクスポートされます。 ::
228
229     export CFLAGS
230     if $(equal $(OSTYPE), Win32)
231         CFLAGS += /DWIN32
232     else
233         CFLAGS += -UWIN32
234
235 .. index::
236    single: export
237    single: return
238 .. _label6.3.2:
239
240 6.3.2 エクスポートされた区域から値を返す
241 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
242 .. This feature was introduced in version 0.9.8.5.
243
244 *この機能はバージョン0.9.8.5で導入されました。*
245
246 .. The use of export does not affect the value returned by a block. The value is computed as usual, as the value of the last statement in the block, ignoring the export. For example, suppose we wish to implement a table that maps strings to unique integers. Consider the following program.
247
248 ブロックによって返された値は ``export`` を使用してもエクスポートされません。この値は普通に計算された場合、ブロック最後の状態の値として解釈され、エクスポートを無視します。例えば、私たちはマップの文字列をユニークな整数値に改良したテーブルを作りたいと思い、以下のプログラムを考えたとします。 ::
249
250     # 空のマップ
251     table = $(Map)
252
253     # テーブルにエントリーを追加
254     intern(s) =
255         export
256         if $(table.mem $s)
257             table.find($s)
258         else
259             private.i = $(table.length)
260             table = $(table.add $s, $i)
261             value $i
262
263     intern(foo)
264     intern(boo)
265     intern(moo)
266     # "boo = 1" と出力
267     println($"boo = $(intern boo)")
268
269 .. Given a string s, the function intern returns either the value already associated with s, or assigns a new value. In the latter case, the table is updated with the new value. The export at the beginning of the function means that the variable table is to be exported. The bindings for s and i are not exported, because they are private.
270
271 文字列 ``s`` が与えられると、関数 ``intern`` は ``s`` に既に関連付けられている値を返し、そうでない場合は新しい値を関連付けます。この場合、このテーブルは新しい値にアップデートされます。関数の初めに ``export`` をつけることによって、 ``table`` 変数はエクスポートされます。一方、 ``s`` や ``i`` に束縛されている値はプライベートなので、エクスポートされません。
272
273 .. Evaluation in omake is eager. That is, expressions are evaluated as soon as they are encountered by the evaluator. One effect of this is that the right-hand-side of a variable definition is expanded when the variable is defined.
274
275 omakeでの評価は先行して行われます。これは評価文に遭遇した場合、即座に式の評価が行われることを意味しています。この効果の一つとして、変数が定義されたときに、右側の変数定義が展開されることが挙げられます。 ::
276
277     osh> A = 1
278     - : "1"
279     osh> A = $(A)$(A)
280     - : "11"
281
282 .. In the second definition, A = $(A)$(A), the right-hand-side is evaluated first, producing the sequence 11. Then the variable A is redefined as the new value. When combined with dynamic scoping, this has many of the same properties as conventional imperative programming.
283
284 二番目の定義文の右側 ``A = $(A)$(A)`` は初めに評価され、シーケンス ``11`` が生成されました。変数 ``A`` は新しい値として再定義されます。動的なスコーピングを用いて束縛した場合、これは従来の命令型プログラミングと同じ多くの特性を持ちます。 ::
285
286     osh> A = 1
287     - : "1"
288     osh> printA() =
289         println($"A = $A")
290     osh> A = $(A)$(A)
291     - : "11"
292     osh> printA()
293     11
294
295 .. In this example, the print function is defined in the scope of A. When it is called on the last line, the dynamic value of A is 11, which is what is printed.
296
297 この例では、出力関数は ``A`` のスコープ中で定義されます。最後の行でこの関数が呼び出されたとき、 ``A`` の動的な値は ``11`` であるので、この値が出力されます。
298
299 .. However, dynamic scoping and imperative programming should not be confused. The following example illustrates a difference. The second printA is not in the scope of the definition A = x$(A)$(A)x, so it prints the original value, 1.
300
301 しかしながら、動的なスコーピングと命令型のプログラミングは混同すべきではありません。以下の例では違いについて示しています。二番目の ``printA`` は ``A = x$(A)$(A)x`` が定義されているスコープには存在していませんので、この関数は元の値 ``1`` を出力します。 ::
302
303     osh> A = 1
304     - : "1"
305     osh> printA() =
306         println($"A = $A")
307     osh> section
308              A = x$(A)$(A)x
309              printA()
310     x11x
311     osh> printA()
312     1
313
314 .. See also Section 7.5 for further ways to control the evaluation order through the use of “lazy” expressions.
315
316 遅延評価式の使用で評価順序を制御する詳細については、":ref:`label7.5`"を参照してください。
317
318 .. index::
319    single: オブジェクト
320    single: extends
321    single: class
322    single: instanceof
323 .. _label6.4:
324
325 6.4 オブジェクト
326 ----------------------------------
327 .. omake is an object-oriented language. Everything is an object, including base values like numbers and strings. In many projects, this may not be so apparent because most evaluation occurs in the default toplevel object, the Pervasives object, and few other objects are ever defined.
328
329 omakeはオブジェクト指向型言語です。数や文字列のような基本的な値を含む、すべてはオブジェクトで表現されます。多くのプロジェクトの場合、通常のトップレベルのオブジェクト中でほとんどの式が評価されるため、これを見ることはあまりありませんが、 ``Pervasives`` オブジェクトと、2,3個の他のオブジェクトが最初から定義されています。
330
331 .. However, objects provide additional means for data structuring, and in some cases judicious use of objects may simplify your project.
332
333 しかしながら、オブジェクトはデータを構築するための追加手段を提供し、さらにオブジェクトを慎重に使用することで、あなたのプロジェクトをより簡単にしてくれるでしょう。
334
335 .. Objects are defined with the following syntax. This defines name to be an object with several methods an values.
336
337 オブジェクトは以下の構文で定義されます。これは ``name`` をいくつかのメソッドと値を持ったオブジェクトとして定義しています。 ::
338
339     name. =                     # += も同じくらいよく使います
340        extends parent-object    # なくても構いません
341        class class-name         # なくても構いません
342
343        # フィールド
344        X = value
345        Y = value
346
347        # メソッド
348        f(args) =
349           body
350        g(arg) =
351           body
352
353 .. An extends directive specifies that this object inherits from the specified parent-object. The object may have any number of extends directives. If there is more than on extends directive, then fields and methods are inherited from all parent objects. If there are name conflicts, the later definitions override the earlier definitions.
354
355 ``extends`` 文はこのオブジェクトが指定された ``parent-object`` に継承されていることを指定します。オブジェクトは任意の数の ``extends`` 文を含めることができます。もしおおくの ``extends`` 文が存在した場合、すべての親オブジェクトのメソッドとフィールドは継承されます。もし名前が衝突していた場合、前の定義は後の定義でオーバーライドされます。
356
357 .. The class directive is optional. If specified, it defines a name for the object that can be used in instanceof operations, as well as :: scoping directives discussed below.
358
359 ``class`` 文はなくても構いません。もし指定されていた場合、 ``instanceof`` 演算子を使うことでオブジェクト名を新たに定義することができるようになります。これは下で議論する ``::`` スコープ文と同様です。
360
361 .. The body of the object is actually an arbitrary program. The variables defined in the body of the object become its fields, and the functions defined in the body become its methods.
362
363 オブジェクトには任意の内容のプログラムを記述できます。オブジェクトの中に定義された変数はフィールドと定義され、関数はメソッドと定義されます。
364
365 .. index::
366    single: フィールド
367    single: メソッド
368 .. _label6.5:
369
370 6.5 フィールドとメソッドの呼び出し
371 ----------------------------------
372 .. The fields and methods of an object are named using object.name notation. For example, let's define a one-dimensional point value.
373
374 オブジェクトのフィールドとメソッドは ``object.name`` 表記を用いて命名されます。例えば、一次元の点の値について定義してみましょう。 ::
375
376    Point. =
377       class Point
378
379       # 通常の値
380       x = $(int 0)
381
382       # 新しい点を生成
383       new(x) =
384          x = $(int $(x))
385          return $(this)
386
387       # ひとつ進める
388       move() =
389          x = $(add $(x), 1)
390          return $(this)
391
392    osh> p1 = $(Point.new 15)
393    osh> value $(p1.x)
394    - : 15 : Int
395
396    osh> p2 = $(p1.move)
397    osh> value $(p2.x)
398    - : 16 : Int
399
400 .. The $(this) variable always represents the current object. The expression $(p1.x) fetches the value of the x field in the p1 object. The expression $(Point.new 15) represents a method call to the new method of the Point object, which returns a new object with 15 as its initial value. The expression $(p1.move) is also a method call, which returns a new object at position 16.
401
402 ``$(this)`` は常に現在のオブジェクトに置き換える変数です。式 ``$(p1.x)`` はオブジェクト ``p1`` の ``x`` の値を呼び出します。式 ``$(Point.new 1)`` は ``Point`` オブジェクトの ``new`` メソッドを呼び出す式で、初期値として15が保持された新しいオブジェクトを返します。 ``$(p1.move)`` もメソッドの呼び出しで、16が保持された新しいオブジェクトを返します。
403
404 .. Note that objects are functional — it is not possible to modify the fields or methods of an existing object in place. Thus, the new and move methods return new objects.
405
406 オブジェクトは関数的であり、その場で存在しているオブジェクトのフィールドやメソッドを修正することは不可能であることに注意してください。よって、 ``new`` と ``move`` メソッドは新しいオブジェクトを返します。
407
408 .. index::
409    single: オーバーライド
410 .. _label6.6:
411
412 6.6 メソッドのオーバーライド
413 ----------------------------------
414 .. Suppose we wish to create a new object that moves by 2 units, instead of just 1. We can do it by overriding the move method.
415
416 1つ移動させる代わりに、2つ移動させるメソッドを持った新しいオブジェクトを作ることについて考えてみましょう。 ``move`` メソッドをオーバーライドすることでこれを実現することができます。 ::
417
418    Point2. =
419       extends $(Point)
420
421       # moveメソッドをオーバーライド
422       move() =
423          x = $(add $(x), 2)
424          return $(this)
425
426    osh> p2 = $(Point2.new 15)
427    osh> p3 = $(p2.move)
428    osh> value $(p3.x)
429    - : 17 : Int
430
431 .. However, by doing this, we have completely replaced the old move method.
432
433 しかし、これを行うと古い ``move`` メソッドは完全に置き換わります。
434
435 .. _label6.7:
436
437 6.7 親の呼び出し
438 ----------------------------------
439 .. Suppose we wish to define a new move method that just calls the old one twice. We can refer to the old definition of move using a super call, which uses the notation $(classname::name <args>). The classname should be the name of the superclass, and name the field or method to be referenced. An alternative way of defining the Point2 object is then as follows.
440
441 新しい ``move`` メソッドを、古い ``old`` メソッドを二回呼び出すことで定義したい場合について考えてみましょう。これは表記 ``$(classname::name <args>)`` を用いることで親を呼び出すことができます。 ``classname`` は親クラスの名前で、 ``name`` のメソッドやフィールドが関連付けられている必要があります。それでは、 ``Point2`` オブジェクトを別の方法で定義してみましょう。 ::
442
443    Point2. =
444       extends $(Point)
445
446       # 古いメソッドを2回呼び出す
447       move() =
448          this = $(Point::move)
449          return $(Point::move)
450
451 .. Note that the first call to $(Point::move) redefines the current object (the this variable). This is because the method returns a new object, which is re-used for the second call.
452
453 最初の ``$(Point::move)`` の呼び出しは現在のオブジェクト( ``this`` 変数)を再定義していることに注意してください。なぜならこのメソッドは新しいオブジェクトを返し、二回目の呼び出しで再利用されるからです。