OSDN Git Service

a7d6fd74fdc0c466ee062e244a606a6209fa1524
[ring-lang-081/ring.git] / docs / build / html / _sources / faq.txt
1 .. index::
2         single: よくある質問と回答; はじめに
3
4 ========================
5 よくある質問と回答 (FAQ)
6 ========================
7
8
9 .. index::
10         pair: よくある質問と回答; 第三のプログラミング言語 (YAPL) は必要か?
11
12
13 第三のプログラミング言語 (YAPL) は必要か?
14 ==========================================
15
16 プログラミング言語 Supernova では「I want window and the window title is hello world.」と入力すると
17 “Hello, World!” のウィンドウタイトルで GUI ウィンドウを作成できます。
18
19 つまり、自然言語コードにより「英語のように制限なくプログラミングで人間の言語能力を発揮できる」ことを発見しましたが、
20 実現には新しいプログラミング言語が必要です。
21
22 (1) 汎用性
23
24 (2) 実用性
25
26 (3) 非常に手軽な方法で自然言語プログラムの作成ができます。
27
28 使いやすく、生産性を最大限まで押し上げることができるシステムを享受できます。
29
30 目的を達成する最良の方法として Ring を作成しました。
31
32 Supernova はアイディアの検証であり、どのような利点と欠点があるかについての見識を得るために役に立ちました。
33 新しいアイディアの検証後に実用的なプログラミング言語があります。
34 Supernova の後に Ring があります。 ABC の後に Python が存在するのと同じ物語です。
35 Python は ABC の問題を回避していますが ABC の利点をもたらします。
36 Ring は Ruby と Ruby on Rails (ROR) の伝説を学んでいます。
37 プログラミング言語の実力は、汎用プログラミング言語の直接的な用法による優れたフレームワークに最も現れます。
38 また Ring には明確な目的と動機である「次世代版 Programming Without Coding Technology (PWCT) ソフトウェアの開発」があり、
39 C 言語で Unix オペレーティングシステムが設計されたことも学んでいます。
40 言い換えれば、各々の設計判断で決定する目標があります。
41
42 さて、質問です。計算機プログラミングの概念に関する知識を持たずに、非常に強力なソフトウェアを製作できますか? 科学的な答えは「ビジュアル・プログラミング」と「自然言語プログラミング」です。
43 実際には、ほかに問題をもたらすことなく、パラダイムを切り替えることはありません。
44
45 Ring (コンパイラ + 仮想計算機) の設計と開発、および C コードの生成では、
46 ビジュアル・プログラミング言語「Programming Without Coding Technology (PWCT)」を 100% 使用しています (一行たりとも手作業でのコーディングはしていません)。
47
48 Programming Without Coding Technology (PWCT) の利点は?
49
50 (1) 高速化。
51
52 (2) シンタックスエラーとは無縁となります。
53
54 (3) 高水準の抽象化となるためコードの理解と管理は容易になります。
55
56 (4) コードの記述はすべて管理できるため致命的な欠点はなくなります。
57
58 上述のアイディアへの対応、パラダイム切り替え時に発生する問題の解決、強力なビジュアル・プログラミングツールの開発のための言語設計 (Qt対応などユーザインタフェースの作成機能を最重要視)、未来のコード不要プログラミング (自然言語の使用) 対応のための設計、実用的手法による自然言語プログラミングの実現、多種多様な方法での問題解決、および画期的かつ問題解決方法に関するアイディアの支援。
59
60 そして、C, C++, C#, Lua, PHP, Python, Ruby, Harbour, Basic と Supernova などのプログラミング言語の豊富な経験とビジュアル・プログラミング (使用経験十年以上)、および自然言語プログラミング (使用経験五年以上) の長期にわたる研究の集大成として、現役プログラマの認識へ変革をもたらし実用プログラミング言語の新天地と成るべく Ring を設計・開発しました。
61
62 プログラミング言語もそうですが、ソフトウェアの分野・用途を問わず、プログラマ、または開発者は意見や批評をする自由があります。 Ring も例外ではなく、ドキュメントの練度・整備不足による誤解、あるいはプログラマによく知られているがために背景にあるアイディアを見落してしまい、新規性がないと評価・判断を誤り、誤解されてしまう各種機能があります。
63
64 設計段階から実装段階へ移行後に、新たに自然言語インタフェースの実装を行ってから、
65 ソフトウェアを言葉で表現することにより、プログラミングを開始します (筆者としては、アイジャル・メソッドは自由であり、
66 移行段階や移行時期についての決定は行いません)。
67
68 Ring は新興プログラミング言語であるため、選択肢は三つあります:
69
70 (1) 今は気にしません。
71
72 (2) Ring の将来について考え、プログラミング言語に関する考えを理解して貢献したいのでしたら、ご支援をお願いします。
73
74 (3) ご期待に添えず申し訳ございません。また数年後の使用再開をお待ちしております。
75
76 まとめ
77 ------
78
79 * Programming Without Coding Technology (PWCT) 2.0 の完成後は Ring で高品質かつ大規模ソフトウェアを開発できるようになります。
80
81 * 宣言型と自然言語パラダイムを段階的に押し進めていきます。
82
83 * 次の公開版では、ネットワーク・プログラミングと平行性のために、新しいパラダイムの実装計画があります。去年、簡易試作品で新しいパラダイムを検証しました。なお、将来の公開版で Ring と統合する予定です。
84
85
86 .. index::
87         pair: よくある質問と回答; なぜ弱い型付けを採用したのですか?
88
89 なぜ弱い型付けを採用したのですか?
90 ==================================
91
92 これは最初の目標で重要なことです。
93 高速化と違和感の排除になるからです。
94 最初の規則: 最初のデータ型は最後の結果に影響します。
95 例えば \"Print : \" + 5 を入力すると、最初に文字列の 5 が表示された後に 5 は文字列へ変換されます。
96 そして 5 + \"10\" と入力すると最初に数値の \"10\" が表示された後に \"10\" は 10 へ変換されます。
97 これは同じ演算子を使用して数値と文字列との間で、すばやく変換するのに大いに役に立ちます。
98 変換を防ぎたい場合は (変換を防ぐコードを記述します)、コードの記述量がより少ない (さらに削除可能) ことに気付くと思います。
99
100 弱い型付け = 自動変換と *自動処理* は *優れたもの* であり、
101 正しく使用されている場合は *手動処理* より優れています。
102
103 .. index::
104         pair: よくある質問と回答; Lisp や Smalltalk よりも Ring を選ぶ利点は?
105
106 Lisp や Smalltalk よりも Ring を選ぶ利点は?
107 ============================================
108
109 Smalltalk と Lisp は、すばらしいプログラミング言語あり、背景にある様々な概念を気に入っています。
110 しかし、問題に基づいて適切なプログラミング言語を選択した後であれば、問題を定義できると確信しています。
111 筆者には解決したい問題があり、この問題において、前述のすばらしいプログラミング言語は理想的ではなかったので Ring を設計しました。
112
113 新しいプログラミング言語を設計するとき、過去から学べますが、
114 将来を見据えて未来へ向かって進まなくてダメなのです。おそらく、
115 読者は自然言語プログラミングの知識に関して、古典的知識に基づいていることは筆者も同意しますが、
116 別技法の実践により、これを実務に取り入れることができることを確認しています。
117 自然言語に関して読者が誤解していることは *文脈依存* です。
118 つまり、アイディアの表現方法に関して色々と考えることで使用できるようになります。
119
120 用例 : I want window contains 3 buttons.
121
122 一文で四つのオブジェクト (ウィンドウと三つのボタン) の作成を行い、ウィンドウへボタンを追加しました。
123 このような様々な物事を取り入れるのが、自然言語プログラミングの考えかたです。
124
125 .. index::
126         pair: よくある質問と回答; ネイティブ C や C++ よりも Ring を選ぶ利点は?
127
128 ネイティブ C や C++ よりも Ring を選ぶ利点は?
129 ==============================================
130
131 Ring 言語では、多種多様なプログラミングパラダイムをまとめて扱うことができます。
132
133 (1) 言語構成要素では、類似の概念に関して類似のシンタックスを使用するため、あるプログラミングパラダイムから別のプログラミングパラダイムへの移行は容易です。
134
135 (2) パラダイムには相互作用性があり、ソフトウェアでは異なる階層で併用されます。
136         例えば、ゲームエンジンの作成はオブジェクト指向プログラミングで、
137         ゲームのコードは宣言型プログラミング、または自然言語プログラミングで記述を行い、
138         シーンの背後では宣言型、または自然言語のコードはオブジェクト指向クラスを使えます。
139
140 (3) Ring は C/C++ よりも生産性が高く、違和感がありません。
141
142 (4) Ring は、動的プログラミング言語です。実行中にコードの生成と実行ができます。 Ring は動的型付け言語であり、柔軟性のために弱い型付けを採用しています。
143
144 (5) ガベージコレクターは、世代間 (エスケープ解析) および参照カウント方式で実装しています。非常に高速であり、さらにプログラマへ制御権を委任することで、いつでもメモリからデータを削除できます。
145
146 (6) C/C++ ライブラリを使えます。 Ring には C 関数または C++ クラスからラッパーを作成するために、コード生成器が付属しています。さらなる処理能力を求めている、またはもっとライブラリを使用する必要がある場合は、簡単に実現できます。
147
148
149 .. index::
150         pair: よくある質問と回答; Ring と Python との違いは?  Ring はオープンソースなの?
151
152 Ring と Python との違いは?  Ring はオープンソースなの?
153 ========================================================
154
155 もちろん。 Ring はオープンソースです (MIT ライセンス)。
156
157 全般的に筆者は Python と Ruby が好きですが、筆者には目的となる単純明快な変更があります。
158
159 (1) 英数大小文字の区別はしません。
160
161 (2) リストのインデックスは 1  から開始します。
162
163 (3) 関数の定義前に呼び出せます。
164
165 (4) Python 風のシンタックスを使用しない (インデント、self の使用、pass & _)
166
167 (5) 弱い型付け (コンテキストに基づいた型の間での自動変換)
168
169 (6) プログラムは、単純明快な一定の構造に従います (ステートメントの後に関数、続いてパッケージとクラス)。
170
171 (7) 代入と値のテストで ‘=’ 演算子の使用。
172
173 重要な変更は、
174
175 (1) 数日で習得できる単純明快な小規模プログラミング言語: Ring コンパイラ + 仮想計算機 = 約 20,000 行の ANSI C コード (すべてのプラットフォームでコンパイル可能)。ほかにライブラリ関連と C/C++ プログラム用のオプションで 500,000 行。
176
177 (2) ガベージコレクター: エスケープ解析・参照カウント方式の採用、および代入演算子の使用によりメモリの削除を行う機会をプログラマが決定する権限を与えています。
178
179 (3) 簡潔なシンタックス: Ring では、行は重要ではありません。 ; の記述または ENTER を押してステートメントを区切る必要はありません。
180
181 (4) 直接、オブジェクトの属性とメソッドを使用した後は { } で、オブジェクトへアクセスします。
182
183 (5) 自然言語プログラミング: オブジェクト指向プログラミングに基づき Ring を使うと違和感のない自然なインタフェースの作成が非常に簡単になります。
184
185 (6) 入れ子構造の宣言型プログラミング
186
187 さらに、 Ring の目的を達成するために、画期的な機能が追加されています (参照: 言語設計 - 明確な目標のための設計)。
188
189
190 .. index::
191         pair: よくある質問と回答; Perl, PHP, Python や Ruby よりも Ring を使用する利点は?
192
193 Perl, PHP, Python や Ruby よりも Ring を使用する利点は?
194 ========================================================
195
196 (1) Ring は多機能で違和感がない上に、画期的で新規性があります。コードも美しく、簡潔で分かりやすく記述できます。 Ring はプログラミングに関する様々なことを考えさせられます。
197 (2) Ring は小規模言語として設計されています (Lua 言語からの教訓)。
198 (3) Ring は単純明快です (BASIC と Clipper/Harbour 言語からの教訓)。
199 (4) Ring はより自然言語的です (Supernova 言語からの教訓)。
200 (5) Ring はより宣言的です (REBOL と QML 言語からの教訓)。
201 (6) Ring の実装は透過性があり、視覚的であり、さらに豪華な機能があります。
202
203 なお、 Ring は PHP, Lua  Tcl や Smalltalk などの改良品や代用品として設計しておりません。
204
205 .. index::
206         pair: よくある質問と回答; C# や Java よりも Ring を使用する利点は?
207
208 C# や Java よりも Ring を使用する利点は?
209 =========================================
210
211 (1) 簡潔なコード (きれいで違和感がない)、生産性と柔軟性の向上。
212
213 (2) 宣言型プログラミング、および自然言語プログラミングに関する対応の改善。
214
215
216 .. index::
217         pair: よくある質問と回答; 関数型プログラミングへの対応が言及されていますが、これは他になにが起きますか?
218
219 関数型プログラミングへの対応が言及されていますが、これは他になにが起きますか?
220 ==============================================================================
221
222 このコードに関する質問です:
223
224 .. code-block:: ring
225
226         f = func {
227             a = 42
228             return func { return a }
229         }
230
231         innerF = call f()
232         call innerF()
233
234 実行結果:
235
236 .. code-block:: none
237
238         Using uninitialized variable : a In function _ring_anonymous_func_16601()
239
240 回答:
241
242 * これは無名関数であり、クロージャー (関数閉包) ではありません。
243
244 * この世界の開発者たちがクロージャーの実装を要望しましたが、 Ring 言語の開発で新しい機能を追加することは Ring 言語の目的と精神に反することです。
245
246 * 関数とステートを統合したいときはクラスとオブジェクトを使うのが明確な解決方法です。
247
248 * リストを使用してリストの内側に無名関数を記述すると、ステートと関数のあるリストを返せます。なお、使用時は関数へリストを渡します。
249
250 * eval() および substr() を使うと、無名関数を返す前に変数の値を直接追加できます。
251
252 * 関数の定義時に、ほかのスコープを保護します。Ring では最大で三種類のスコープに属する各場所で、三種類のスコープ規則があります (グローバル、オブジェクトのスコープ、およびローカルスコープ)。
253
254 * ほかのプログラミング言語を、全て真似をする必要もありませんし、真似しても全て得られるわけではありません! そのように考えているならば、非常に複雑怪奇なプログラミング言語を作成するか、時間を節約するために他のプログラミング言語を使うと思います。
255
256 * 新しいプログラミング言語の学習、または勉強に専念して (Ring の新しいところや優れたところ)、 いつから使い始めるかについて考えることがあります。数ヶ月前に、公開されたプログラミング言語と数年前に開発が始まったプログラミング言語を比較すること、および現在の世界で使用されているプログラミング言語をすべて理解したと錯覚しないでください。
257
258 * 各々のプログラミング言語にある理解できないことが、ほかのプログラミング言語では特徴となります。アイディアは機能でありません。すべての機能に隠された精神と才能です。
259
260
261 .. index::
262         pair: よくある質問と回答; シンタックスの処理ではなく自作言語の定義機能があり、コードなどで構文解析の使用を可能にしている理由は?
263
264 シンタックスの処理ではなく自作言語の定義機能があり、コードなどで構文解析の使用を可能にしている理由は?
265 ======================================================================================================
266
267 つまり、画期的です - 構文解析関連の学習をせずに、自然言語ステートメントを作成できます。
268 聡明な判断により、クラスを使用します (後でコンテキストに基づき
269 様々なステートメントへ対応するクラスを併用できるようにするためです -
270 ステートメントの変更と変換など様々なことができます)。
271 また、すべての Ring ステートメントを Ring 環境から使えるようにするステートメントを追加してあります。
272
273
274 .. index::
275         pair: よくある質問と回答; ループの中断時に数値の指定ができる理由は?
276
277 ループの中断時に数値の指定ができる理由は?
278 ==========================================
279
280 Ring は小規模プログラミングと大規模プログラミングに対応しています。
281 目的と手段に基づいて使用する機能を選択します。
282 お望みとあれば、プログラマはプログラミング言語で粗悪なコードを記述できます。
283 このアイディアは、柔軟性破壊などの問題を起こさせないために、言語設計でエラー対策を盛り込む必要があります。
284
285 例えば、 Linux カーネルと Ruby の実装としてコードの一部を読むと、普段は使用しない一般的規則による実用的な GOTO の用法と用例を理解するでしょう。また、優れたプログラマは、いつ規則を破るべきかを知っています。
286 Ring において GOTO は使用不能であり、実装予定については一切言及しません。
287 しかし、一階層以上のループを中断する機能や下位関数からループを中断する機能は、小規模プログラムでは実用的です。
288
289 とにかく、これらは言語により追加された小さな新機能の一部です (重要なアイディアではありません)。
290
291
292 .. index::
293         pair: よくある質問と回答; Ring で ‘See’, ‘Give’, ‘But’ および ‘Ok’ キーワードを採用する理由は?
294
295 Ring で ‘See’, ‘Give’, ‘But’ および ‘Ok’ キーワードを採用する理由は?
296 =============================================================================
297
298 See と Give は “反対の動作” ではありませんが、プログラマがしたいことをするために選びました。
299
300 画面から処理の過程や結果を確認したいときは ‘See’ です。
301
302 キーボードからの標準入力をプログラムへ与えたいときは ‘Give’ です。
303
304 “but” や “ok” を選んだ根拠は簡単に書けるキーワードだからです。
305
306 また elseif/elif/elsif は文脈ごとに違うキーワードを使い分ける必要があるため "but" のほうが覚えやすいです。
307
308 これらは Ring 1.1 以降ではオプション扱いです。
309
310 ‘See’ と ‘Give’ の代わりに ‘Put’ と ‘Get’ を使えます。
311
312 ‘But’ と‘Ok’ の代わりに‘elseif’ または ‘end’ を使えます。
313
314 それは読者の選択にゆだねられています。 Ring には複数の記法とシンタックスの柔軟性があります。
315
316 また、自然言語の新規定義、および言語のキーワードと演算子を変更可能です。
317
318
319 .. index::
320         pair: よくある質問と回答; Ring においてデータ型の背景にある哲学とは?
321
322 Ring においてデータ型の背景にある哲学とは?
323 ===========================================
324
325 Ring は開発で求められる基本概念を実装しています! 可能な限り、基本概念は単純明快・小規模を維持するのが目標の一つです。
326
327 Ring におけるリストの用法で可能なこと
328
329 * 配列の作成 (単体データ型)
330 * リストの作成 (混成データ型)
331 * ツリーの作成 (入れ子による配列)
332 * インデックスに文字列を使用 (ディクショナリー・ハッシュテーブル風の記法)
333
334 同じ原則は、これらを数値に使うときにも適用されます。
335
336 * int 値
337 * double 値
338 * Boolean 値 (True/False)
339
340 この事例の原則は、下記を文字列へ格納するときにも適用されます。
341
342 * 文字
343 * テキスト (一行以上)
344 * バイナリデータ
345 * 日付
346 * 日時
347 * NULL 値 (空の文字列)
348
349 プログラマが新しいデータ型を定義することで、言語の定義済みデフォルト型として
350 使用できるオブジェクト指向への対応。つまり、 + 演算子のオーバーロードがあります。
351
352 よって、このようになりました。
353
354 * 高速化のため、 Ring 言語では基本型 (文字列、数値、リスト、オブジェクト) が扱えます。
355 * オブジェクト指向プログラミングを採用しています。アプリケーションの問題領域に従い、新しい型を追加することで拡張できる柔軟なプログラミング言語です。
356
357
358 .. index::
359         pair: よくある質問と回答; Ring でのブール値とは?
360
361 Ring でのブール値とは?
362 =======================
363
364 コードでブール式の結果を判定するときに
365
366 true (真) では 1 を、および false (偽) では 0 を使えます。
367
368 see 命令で値を表示するときに 1 は (true) であり、 0 は (false) を表示します。
369
370 理由は?
371
372 Ring には四種類の型があるからです。
373
374 (1) 数値
375
376 (2) 文字列
377
378 (3) リスト
379
380 (4) オブジェクト
381
382 最初の型 (数値) は、 int (整数)、倍精度数、ブール値を表すために使用されます。
383
384 二番目の型 (文字列) は、 char (文字) 型、文字の配列、日付と時刻を表すために使用されます。
385
386 三番目の型 (リスト) は配列型であり、複合型から構成される配列として、ハッシュ (ディクショナリ)、ツリーなどを表すために使用されます。
387
388 オブジェクトは、 Ring のクラス (全てのクラス) または C/C++ 関数、メソッドを呼び出すことで得られる C ポインタから作成されたオブジェクトです。
389
390 なぜですか?
391
392 Ring はプログラマ、開発者が様々な作業で使えるように
393 最も単純明快な概念で設計されています。問題領域の定義に関心があるならば、
394 プログラマ、開発者は様々な型を取得するために、新しいクラス (および演算子のオーバーロード)を作成することで言語をカスタマイズします。
395
396 どうしてですか?
397
398 単純なことは良いことであり、習得と記憶が簡単だからです! さらに、これは基本型で表現可能な高水準型の間における変換の柔軟性があります。
399
400
401 .. index::
402         pair: よくある質問と回答; Ring に “Main” 関数を実装した理由は?
403
404 Ring に “Main” 関数を実装した理由は?
405 =======================================
406
407 Main 関数は非常に重要であり、グローバルスコープの代わりにローカル変数を使用する
408 ステートメントを記述したいときに必要です。
409
410 用例:
411
412 .. code-block:: ring
413
414         x = 10
415         myfunc()
416         See "X value = " + X  # ここでは x の値は (10) と想定します。
417                               # しかし myfunc() で x を使用しているため別の値 (6) になります!
418         Func myfunc
419            for x = 1 to 5
420                See x + nl
421            next
422
423 実行結果:
424
425 .. code-block:: ring
426
427         1
428         2
429         3
430         4
431         5
432         X value = 6
433
434 Main 関数の使用
435
436 .. code-block:: ring
437
438         Func Main
439            x = 10
440            myfunc()
441            See "X value = " + X
442
443         Func myfunc
444            for x = 1 to 5
445                See x + nl
446            next
447
448 実行結果:
449
450 .. code-block:: ring
451
452         1
453         2
454         3
455         4
456         5
457         X value = 10
458
459
460 .. index::
461         pair: よくある質問と回答; Ring のインデックスが 1 から始まる理由は?
462
463 Ring のインデックスが 1 から始まる理由は?
464 ==========================================
465
466 実生活では、三個のリンゴを手に持って数えるとき、
467
468 1 2 3 と数えます。
469
470 0 から数えることはしません。
471
472 質問: ほかのプログラミング言語において、インデックスが必ず 0 から開始されるのか?
473
474 回答: これは、計算機における値とメモリアドレスの取り扱い方法について関係があります。
475
476 用例:
477
478 myarray[5] 配列があります。
479
480 メモリには: myarray のアドレスがあります。
481
482 最初の項目は、アドレスへ格納されます。
483
484 二番目の項目は、アドレスの後などにあります。
485
486 myarray のアドレスで必要となる最初のアドレスを指し示す必要がある場合は
487
488 myarray + 0 の結果は、最初にある項目を指し示すため、そのまま myarray[0] と入力します。
489
490 myarray + 1 の結果は、二番目などにある項目を指し示すため、 myarray[1] と入力します。
491
492 このような仕組みは、低水準言語またはハードウェア寄りの言語では良いことです。
493
494 しかし、アプリケーション開発用に設計された高級言語では、違和感のない仕組みのほうが優れています。
495
496 用例:
497
498 .. code-block:: ring
499
500         mylist = [1,2,3,4,5]
501         for x = 1 to len(mylist)
502                 see x + nl
503         next
504
505 前述の用例では、配列の長さは 1 から開始します。
506 0 から開始するインデックスを記述する場合は、
507
508 .. code-block:: ring
509
510         for x = 0 to len(mylist)-1
511
512 また、 ほかのプログラミング言語の for ループのようにする方法を覚えておいてください。
513
514 .. code-block:: ring
515
516         for(x=0 ; x<nMax ; x++ )
517
518 \< 演算子を使用してください! (ZeroLib も使えます)
519
520
521 .. index::
522         pair: よくある質問と回答; Ring が英数大小文字を区別しない理由は?
523
524 Ring が英数大小文字を区別しない理由は?
525 =======================================
526
527 (1) もっとひとにやさしくするため。
528
529 (2) Ada, SQL, Pascal, Delphi, Visual Basic, Visual FoxPro に影響を受けたため。
530
531 (3) 自然言語プログラミングの対応において効果的であるため。
532
533 (4) プログラミング言語のキーワードを記述するとき、好みの記法を選択できるようにするため。
534
535 .. code-block:: ring
536
537         see "lower case!"
538
539 .. code-block:: ring
540
541         SEE "UPPER case!"
542
543 .. code-block:: ring
544
545         See "First Letter is UPPER case!"
546
547 (5) 手軽なテストを書くために、 “Variable” ではなく “variable” を入力してしまった後にエラーメッセージになるのを防ぐため。
548
549 (6) “dosomething()” ではなく、 “Dosomething()” を入力してしまった後にエラーメッセージになるのを防ぐため。
550
551 (7) Ring では、変数、メソッド名、およびクラス名の間で名前衝突を起こさないため。
552
553 変数名として、 person および クラス名として Person を記述できます。
554
555 .. code-block:: ring
556
557         person = new Person
558         class Person
559                 name address phone
560
561
562 大小英数を区別したい場合は、キーワードと演算子の再定義 (またはプリプロセッサを自作)、および全角英数を使用してください。
563
564 .. index::
565         pair: よくある質問と回答; 代入演算子で深いコピーを使用する理由は?
566
567 代入演算子で深いコピーを使用する理由は?
568 ========================================
569
570 “つまり、実行性能の利得に関しては疑問と劣悪な等価交換があります。
571         第三者による証明が行われるまで、深いvs浅いコピーの良い手引きとしては深いコピーのほうが好ましいです。”
572         ― スティーブ・マコーネル、コンプリートコードより
573
574 (1) 代入演算子では深いコピーを要求したほうが違和感がありません。
575
576 (2) 深いコピーが不要ならば、使用しないだけで良いです!
577
578 (3) Ring は、できる限り参照の使用を減らすように設計しています。
579
580 (4) Ring は、これが意味がある特別な場合において、参照を単純かつ可能にするために設計されています。
581
582 (5) 関数へのリスト、およびオブジェクト渡すとき、 C/C++ ライブラリからオブジェクトを
583         作成時 (GUI オブジェクトなど)、リストの内側に格納されている
584         オブジェクトを返すときなど、これが当然である場合は参照となります。
585
586 (6) これは機能であり、純粋関数を作成するために使えます。これが必要なとき、
587          stdlib の Value() 関数は、この機能で値によるリストとオブジェクトを渡します。
588
589 (7) 参照が必要なときは、リストを共有管理するためのクラスとオブジェクトの作成を推奨します。
590
591 (8) 様々なロジックエラーを回避することは、アプリケーションの水準ではより安全なことです。
592
593 (9) Ring では、つまらない、細かいことに関して考えずに開発を開始してアプリケーションに専念するため、型を記述しなくても良いです (動的型付け)。
594         また、数値、および文字列の間で明示的変換を記述しなくても良いです (弱い型付け)。
595         さらに、値または参照、および使用の間で選択しなくても良いです。
596         そして、スコープを記述しなくても良いです (レキシカルスコープ)。
597
598 (10) Ring には、スマートガベージコレクター (単純で高速) があります。代入演算子を使用すれば、いつでも好きなときにメモリを直接削除できます。
599         これは参照の削減方法、または管理プログラムから使用することは、当目的を達成するのに大いに有効です。
600         これによる完全な制御があります。
601
602 (11) 参照の作成、および管理の作成を回避したい場合は
603         Object2Pointer() と Pointer2Object() 関数を使用します。
604         しかし、これは Ring の “精神” に反しています。
605
606
607 .. index::
608         pair: よくある質問と回答; Ring にコンストラクタメソッドはありますか?
609
610 Ring にコンストラクタメソッドはありますか?
611 ===========================================
612
613 例えば新しいオブジェクトの作成時、
614
615 .. code-block:: ring
616
617         new point
618
619 1 - Ring で認識されていないときは Ring は新しいオブジェクトの属性で用いる動的メモリ空間を割り当てます。
620
621 2 - Ring は手順①で作成されたオブジェクトのステートで現在のオブジェクトのスコープとローカルスコープを変更します。
622
623 3 - Ring は実行中に、クラスの範囲を移動します (クラス名の末尾、そしてメソッドの先頭)。
624
625 4 - クラスの範囲内にあるすべての命令やコードは、 Ring のコードとして実行されます。
626
627 5 - クラスの範囲が終端に到達、または Return 命令を使うと、制御はクラスの範囲から (新しい場所) へ移動します。
628
629 オブジェクトが追加された全属性は動的属性であるため、これは実行時に追加する属性を制御できます。
630
631 用例:
632
633 .. code-block:: ring
634
635         $3D = False
636         see  new point
637         $3D = True
638         see new point
639
640         class point
641                 x y
642                 if not $3D return ok
643                 z
644
645 実行結果:
646
647 .. code-block:: none
648
649         x: NULL
650         y: NULL
651         x: NULL
652         y: NULL
653         z: NULL
654
655 新しいオブジェクトの作成時、 init() メソッドを直接呼び出すオプションがあります。
656
657 このメソッドはオブジェクトの作成後に、クラスの範囲にあるコードの実行すると呼び出されるため、オブジェクト属性で処理を行うことができます。
658
659
660 .. code-block:: ring
661
662         p1 = new point3d(100,200,300)
663         see p1
664
665         class point3d
666                 x y z
667                 func init p1,p2,p3
668                         x=p1 y=p2 z=p3
669
670
671 .. index::
672         pair: よくある質問と回答; オブジェクトの新規作成時に起きていることは?
673
674 オブジェクトの新規作成時に起きていることは?
675 ============================================
676
677 1 - オブジェクトの作成時に、クラスの範囲にあるコードは実行されます。そして、この範囲にあるコードに基づいたオブジェクトの属性があります。
678
679 2 - Ring は、メソッドの呼び出しを開始するまでオブジェクトに関して気にしません。
680
681 3 - メソッドの呼び出し時に、 Ring はオブジェクトのクラスと親クラスの確認を行い (継承を使用しているならば)、同一クラスに所属する全てのオブジェクトから現在または今後使用するためにメソッドを収集します。
682
683 4 - メソッドは動的であり、各オブジェクトはクラスのメソッドから取得するため、オブジェクトの作成後に、メソッドの追加、オブジェクトまたは作成されたオブジェクトの使用、または同一クラスから作成できます。
684
685 用例:
686
687 .. code-block:: ring
688
689         o1 = new point {x=10 y=20 z=30}
690         o2 = new point {x=100 y=200 z =300}
691
692         addmethod(o1,"print", func { see x + nl + y + nl + z + nl } )
693
694         o1.print()
695         o2.print()
696
697         class point x y z
698
699 実行結果:
700
701 .. code-block:: none
702
703         10
704         20
705         30
706         100
707         200
708         300
709
710
711 .. index::
712         pair: よくある質問と回答; Getter と Setter メソッドでのアクセスにより属性を使えますか?
713
714 Getter と Setter メソッドでのアクセスにより属性を使えますか?
715 =============================================================
716
717 もちろんです。クラスの外側から属性の使用を開始するときに、 Setter/Getter メソッドは自動的に呼び出されます。
718 また、属性を使わずにメソッドを呼び出せます。読者の選択しだいです。
719
720 用例:
721
722 .. code-block:: ring
723
724         o1 = new Developer
725         o1.name = "Mahmoud"  see o1.name + nl
726         o1 { name = "Gal"  see name }
727         o1 { name = "Bert"  see name }
728
729         o1.setname("Marino")
730         see o1.getname()
731
732         Class Developer
733
734                         name language = "Ring Programming Language"
735
736                         func setname value
737                                         see "Message from SetName() Function!" + nl
738                                         name = value + " - " + language
739
740                         func getname
741                                         see "Message from GetName() Function!" + nl + nl
742                                         return "Mr. " + name + nl
743
744 実行結果:
745
746 .. code-block:: none
747
748         Message from SetName() Function!
749         Message from GetName() Function!
750
751         Mr. Mahmoud - Ring Programming Language
752
753         Message from SetName() Function!
754         Message from GetName() Function!
755
756         Mr. Gal - Ring Programming Language
757         Message from SetName() Function!
758         Message from GetName() Function!
759
760         Mr. Bert - Ring Programming Language
761         Message from SetName() Function!
762         Message from GetName() Function!
763
764         Mr. Marino - Ring Programming Language
765
766
767 .. index::
768         pair: よくある質問と回答; クラスを定義している間にグローバルな名前の検索を行う理由は?
769
770 クラスを定義している間にグローバルな名前の検索を行う理由は?
771 ============================================================
772
773 質問は、なぜクラス属性の定義時に
774 グローバル変数との名前衝突を回避しないのですか?
775
776 先頭にオプションの $ 記号で、グローバル変数名の問題解決になることを覚えておいてください。
777 Main 関数は、グローバル変数を避けるために効果があります。
778
779 回答:
780
781 Ring は動的プログラミング言語です。
782
783 実行時に、クラスの属性を決定できます (追加・削除)。
784
785 クラスの属性を定義している間は、実行 (指定のコード) できます。
786
787 用例①
788
789 .. code-block:: ring
790
791         oPerson = new Person
792         Class Person
793            See "Welcome to the Ring language"
794
795 用例②
796
797 グローバル変数に基づき、属性をカスタマイズします。
798
799 .. code-block:: ring
800
801         $debug = true
802         oPerson = new Person
803         see oPerson
804         Class Person
805             if $debug  date=date()  time=time() ok
806
807 前述の用例では、 $debug フラグに true が設定されているとき、
808 オブジェクトのステートへ Date と Time 属性を追加します。
809
810 用例③
811
812 グローバル変数に基づき、オブジェクトのインデックスを格納します。
813
814 .. code-block:: ring
815
816         $ObjectsCount = 0
817         oPerson = new Person
818         see oPerson
819         oPerson2 = new Person
820         see oPerson2
821         Class Person
822               $ObjectsCount++
823               nIndex = $ObjectsCount
824
825 実行結果:
826
827 .. code-block:: ring
828
829         nindex: 1.000000
830         nindex: 2.000000
831
832 一般的な用例:
833
834 * データベースの接続後に、デーブルのカラムを取得します (グローバル変数やオブジェクトを使用)。
835
836 * カラム名に基づき、クラスの属性を作成します。
837
838 * 後でデータベースを修正します - 不要ならば、コードを修正しないでください。
839
840 柔軟性はありますが、すばらしい応答性による強力さがあることを覚えておいてください。
841
842
843 .. index::
844         pair: よくある質問と回答; Ring でグローバル変数とクラスの属性名間の名前衝突を回避しない理由は?
845
846 Ring でグローバル変数とクラスの属性名間の名前衝突を回避しない理由は?
847 =====================================================================
848
849 このような場合の対応策です。
850
851 1 - $ などの特殊記号を使用せずに、グローバル変数を定義するためです。
852
853 2 - クラスには、特別なシンタックスで定義された属性があります (クラスの後に属性名を直接入力します)。
854
855 3 - 属性は、コードの記述とグローバル変数の使用が許されているクラスの範囲で定義されます。
856
857 クラスの範囲内で、 Ring の変数検出方法の変更について提案を受け入れる場合は、この問題よりも更に重要な問題を多発する前に三つの機能のうち一つを破る必要があります。
858
859 Ring のコードをもっと綺麗なものにしておきたいし、 $ を使用する・しないときをプログラマに決定させたいため機能番号①の変更は好ましくありません。
860
861 この機能は気に入っており、プログラマに Self.属性 の入力を強制するのは好みではないので機能番号②の変更は好ましくありません。
862
863 ほとんどのアプリケーションでは、クラスの範囲内でのグローバル変数へのアクセスは非常に重要であるため機能番号③の変更は好ましくありません。
864
865 判断理由は?
866
867 筆者は、この特例を回避するかどうかをプログラマが決めるために、この事例を記載することにしました。
868
869 1 - グローバル変数の使用を回避でき (最良)、 Main 関数 (オプション扱い) を使えます。
870
871 2 - プログラマは変数名の先頭に ``$`` あるいは ``global_`` または ``g_`` などの記号を使えます。
872
873 3 - プログラマは属性を定義するために、クラス名末尾に Self.属性 を使えます。
874
875 一般に、小規模プログラムではグローバル変数と関数を使います。大規模プログラムではクラスとオブジェクトを使いますので、グローバル変数は数本だけに絞るか、または使わないでください。
876
877
878 .. index::
879         pair: よくある質問と回答; ftell() と fseek() でファイルの大きさを取得するには?
880
881 ftell() と fseek() でファイルの大きさを取得するには?
882 =====================================================
883
884 この関数はファイルの読み込みを行わずに、ファイルの大きさを取得します!
885
886 .. code-block:: ring
887
888         func getFileSize fp
889                C_FILESTART = 0
890                C_FILEEND = 2
891                fseek(fp,0,C_FILEEND)
892                nFileSize = ftell(fp)
893                fseek(fp,0,C_FILESTART)
894                return nFileSize
895
896 .. note:: 前述の関数では仮引数として、 fp (ファイルポインタ) を扱います。 fopen() 関数で開いているファイルから fp を取得できます。
897
898 .. code-block:: ring
899
900         fp = fopen("filename","r")
901
902         see  "File Size : " + getFileSize(fp) + nl
903
904 別の解決方法 (ファイルの読み取り):
905
906 .. code-block:: ring
907
908         see len(read("filename"))
909
910
911 .. index::
912         pair: よくある質問と回答; 現在のソースファイルのパスを取得するには?
913
914 現在のソースファイルのパスを取得するには?
915 ==========================================
916
917 この関数で、現在のソースファイルのパスを取得します。
918 そして、パスを扱うための変数へファイル名を追加できます。
919
920 .. code-block:: ring
921
922         cPath = CurrentPath()
923         func currentpath
924                 cFileName = filename()
925                 for x = len(cFileName) to 1 step -1
926                         if cFileName[x] = "/"
927                                 return left(cFileName,x-1)
928                         ok
929                 next
930                 return cFileName
931
932
933 .. index::
934         pair: よくある質問と回答; 関数の定義済み仮引数またはオプションの仮引数とは?
935
936 関数の定義済み仮引数またはオプションの仮引数とは?
937 ==================================================
938
939 定義済み仮引数、またはオプションの仮引数を使用したい場合は、ハッシュ、ディクショナリなどのリストを受け入れてください。
940
941 用例:
942
943 .. code-block:: ring
944
945         sum([ :a = 1, :b = 2])
946         sum([ :a = 1 ])
947         sum([ :b = 2 ])
948         func sum pList
949                 if plist[:a] = NULL pList[:a] = 4 ok
950                 if plist[:b] = NULL pList[:b] = 5 ok
951                 see pList[:a] + pList[:b] + nl
952
953 実行結果:
954
955 .. code-block:: none
956
957         3
958         6
959         6
960
961
962 .. index::
963         pair: よくある質問と回答; リストやディクショナリでキーまたは値のみを表示するには?
964
965 リストやディクショナリでキーまたは値のみを表示するには?
966 ========================================================
967
968 キーまたは値のみを表示したい場合は、項目のインデックスを選択します (1 または 2)。
969
970 用例
971
972 .. code-block:: ring
973
974
975         C_COUNTRY = 1
976         C_CITY = 2
977         mylist = [
978                 :KSA = "Riyadh" ,
979                 :Egypt = "Cairo"
980         ]
981
982         for x in mylist
983                 see x[C_COUNTRY] + nl
984         next
985
986         for x in mylist
987                 see x[C_CITY] + nl
988         next
989
990 実行結果:
991
992 .. code-block:: none
993
994         ksa
995         egypt
996         Riyadh
997         Cairo
998
999
1000 .. index::
1001         pair: よくある質問と回答; リストで nl を表示するときに変な結果になる理由は?
1002
1003 リストで nl を表示するときに変な結果になる理由は?
1004 ==================================================
1005
1006 このコードでは、
1007
1008 .. code-block:: ring
1009
1010         list = 1:5        # list = [1,2,3,4,5]
1011         see list + nl
1012
1013 リストへ改行を追加後にリストを表示します。つまり、通常のリスト表示では、リストの末尾にある改行も表示します。
1014 新しい改行文字を追加したので、改行は二行表示となります。
1015
1016 .. code-block:: ring
1017
1018         See <式>
1019
1020 see 命令は式の最終結果を表示するため、このように式が評価されます。
1021
1022 .. code-block:: ring
1023
1024         nl = char(13) + char(10) # 変更可能な変数!
1025
1026 \+ は演算子です。
1027
1028 .. code-block:: none
1029
1030         文字列 + 文字列 ---> 新しい文字列
1031         文字列 + 数値   ---> 新しい文字列
1032         数値   + 数値   ---> 新しい数値
1033         数値   + 文字列 ---> 新しい数値
1034
1035 リスト + 項目 ---> なにも新規作成されませんが、同じリストへ項目が追加されます。
1036
1037 例外:
1038
1039 数値 + nl ---> 新しい文字列
1040
1041 この例外は数値の表示後に、改行を簡単にできるよう追加されています。
1042
1043 最後の項目を表示した後には、改行が既にあるため、これはリストを表示するためには不要です。
1044
1045
1046 .. index::
1047         pair: よくある質問と回答; StrCmp() の実行結果について解説していただけますか?
1048
1049 StrCmp() の実行結果について解説していただけますか?
1050 ===================================================
1051
1052 まず、 ‘=’ 演算子で直接的に文字列を検査できることを覚えておいてください。
1053
1054 .. code-block:: ring
1055
1056         see strcmp("hello","hello") + nl +
1057         strcmp("abc","bcd") + nl +
1058         strcmp("bcd","abc") + nl
1059
1060 両方とも、同じ文字列の場合は 0 を返します。
1061
1062 abc と bcd は違います。二行目は -1 を返しており三行目は 1 を返します。
1063
1064 二行目では “abc” と “bcd” の比較を行っています。
1065
1066 “abc” = “a” の一文字目と “bcd” = “b” の一文字は等しくありません。
1067 よって “a” != “b” と “a” < “b” の結果となります。
1068
1069 よって “a” != “b” と “a” < “b” の
1070
1071 実行結果は -1 となります。
1072
1073 三行目には “bcd” と “abc” があります。
1074
1075 “bcd” の一文字目は “b” であり “abc” の一文字は= “a” です。
1076
1077 結果は “b” != “a” と “b” > “a” です。
1078
1079 従って、実行結果は 1 となります。
1080
1081 .. note:: ASCII(“a”) は 97 であり ASCII(“b”) は 98 です。よって 97 < 98 であるため “a” は “b” 以下となります。
1082
1083
1084 .. index::
1085         pair: よくある質問と回答; プロジェクトで複数のソースコードを使うには?
1086
1087 プロジェクトで複数のソースコードを使うには?
1088 ============================================
1089
1090 用例:
1091
1092 このようなフォルダがあります。
1093
1094 .. code-block:: none
1095
1096         C:\LRing
1097
1098 このようなファイルがフォルダにあります。
1099
1100 .. code-block:: none
1101
1102         C:\LRing\t1.ring
1103         C:\LRing\mylib.ring
1104         C:\LRing\libs\mylib2.ring
1105
1106 このようなコードが t1.ring ファイルにあります。
1107
1108 .. code-block:: ring
1109
1110         load "mylib.ring"
1111         load "libs\mylib2.ring"
1112         myfunc()
1113         test()
1114
1115 このようなコードが mylib.ring ファイルにあります。
1116
1117 .. code-block:: ring
1118
1119         func myfunc
1120                 see "message from myfunc"+nl
1121
1122 このようなコードが libs\mylib2.ring ファイルにあります。
1123
1124 .. code-block:: ring
1125
1126         func test
1127                 see "message from test" + nl
1128
1129 C:\\LRing フォルダから。
1130
1131 Ring のパスを追加していない場合は、このコマンドで追加できます。
1132
1133 .. code-block:: none
1134
1135         set path=%path%;c:\ring\bin;
1136
1137 Ring フォルダ C:\\Ring のある場所で
1138
1139 実行します。
1140
1141 .. code-block:: none
1142
1143         Ring t1.ring
1144
1145 実行結果:
1146
1147 .. code-block:: none
1148
1149         message from myfunc
1150         message from test
1151
1152
1153 .. index::
1154         pair: よくある質問と回答; この用例で GetChar() を二度使用する理由は?
1155
1156 この用例で GetChar() を二度使用する理由は?
1157 ===========================================
1158
1159 GetChar() 関数は、キーボードバッファから一文字受け取ります。
1160
1161 この用例では、
1162
1163
1164 .. code-block:: ring
1165
1166
1167         While True
1168                 See "
1169                         Main Menu
1170                         (1) Say Hello
1171                         (2) Exit
1172                 "
1173                 Option = GetChar()
1174                 GetChar() GetChar()  # 行の終わり
1175                 # この行で前述の二行を置換できます。
1176                 # Give Option
1177
1178                 if Option = 1
1179                         see "Enter your name : " give cName
1180                         see "Hello " + cName
1181                 else
1182                         bye
1183                 ok
1184         End
1185
1186 GetChar() を三回使用しています。
1187
1188 最初はユーザの選択肢を取得するときに、
1189
1190 .. code-block:: ring
1191
1192         Option = GetChar()
1193
1194
1195 しかし、二回目と三回目があります (バッファから改行文字を受け取ります)。
1196
1197 .. code-block:: ring
1198
1199         GetChar() GetChar()  # 行の終わり
1200
1201 用例: ユーザが選択肢から 1 を選んだ後に ENTER を押します。
1202
1203 ここでは、三文字あります。
1204
1205 * 一文字目は : 数字の 1 です。
1206 * 二文字目は : CHAR(13) です。
1207 * 三文字目は : CHAR(10) です。
1208
1209 Windows において、 CHAR(13) および CHAR(10) は、それぞれ改行となります (すなわち CR+LF)。
1210
1211
1212 .. index::
1213         pair: よくある質問と回答; NULL と isNULL() 関数の用法は?
1214
1215 NULL と isNULL() 関数の用法は?
1216 ===============================
1217
1218 Ring では、未初期化変数を使うと、明示的なランタイムエラーメッセージが表示されます。
1219
1220 用例:
1221
1222 .. code-block:: ring
1223
1224         See x
1225
1226 実行結果:
1227
1228 .. code-block:: none
1229
1230         Line 1 Error (R24) : Using uninitialized variable : x
1231         in file tests\seeuninit.ring
1232
1233 未初期化の属性へアクセスすると、同じことが起こります。
1234
1235 用例:
1236
1237 .. code-block:: ring
1238
1239         o1 = new point
1240         see o1
1241         see o1.x
1242         class point x y z
1243
1244 実行結果
1245
1246 .. code-block:: none
1247
1248         x: NULL
1249         y: NULL
1250         z: NULL
1251
1252         Line 3 Error (R24) : Using uninitialized variable : x
1253         in file tests\seeuninit2.ring
1254
1255 エラーを検査したい場合は、 Try/Catch/End を使用してください。
1256
1257 .. code-block:: ring
1258
1259         Try
1260                 see x
1261         Catch
1262                 See "Sorry, We can't use x!" + nl
1263         Done
1264
1265 実行結果:
1266
1267 .. code-block:: none
1268
1269         Sorry, We can't use x!
1270
1271 さて、 NULL と isNULL() についてお話します。
1272
1273 未初期化の変数を扱おうとしたとき、エラーメッセージが出ます。
1274
1275 これらのエラーは Try/Catch/Done で検査できます。文字列で扱うためには NULL と isNULL() を使用します。
1276
1277 NULL には、空文字列の変数があります。
1278
1279 isNULL() は関数であり、入力が空の文字列、または文字列の内容が “NULL” ならば true (1) を返します。
1280
1281 これらの値 (空の文字列) をテストする必要があり、 DBMS などの外部リソースから “NULL” を有する文字列が入力されることがあるからです。
1282
1283 用例:
1284
1285 .. code-block:: ring
1286
1287         See isNULL(5) + nl +        # 0 の表示
1288         isNULL("hello") + nl +      # 0 の表示
1289         isNULL([1,3,5]) + nl +      # 0 の表示
1290         isNULL("") + nl +           # 1 の表示
1291         isNULL("NULL")              # 1 の表示
1292
1293
1294 .. index::
1295         pair: よくある質問と回答; オブジェクトのあるリストを表示するには?
1296
1297 オブジェクトのあるリストを表示するには?
1298 ========================================
1299
1300 この用例では、オブジェクトのあるリストの表示方法を確認します。
1301
1302 .. code-block:: ring
1303
1304         aList = [[1,2,3] , new point(1,2,3), new point(1,2,3)]
1305         see "print the list" + nl
1306         see alist
1307         see "print the item (object)" + nl
1308         see alist[2]
1309         class point x y z
1310                 func init p1,p2,p3 x=p1 y=p2 z=p3
1311
1312 実行結果:
1313
1314 .. code-block:: none
1315
1316         print the list
1317         1
1318         2
1319         3
1320         x: 1.000000
1321         y: 2.000000
1322         z: 3.000000
1323         x: 1.000000
1324         y: 2.000000
1325         z: 3.000000
1326         print the item (object)
1327         x: 1.000000
1328         y: 2.000000
1329         z: 3.000000
1330
1331
1332 .. index::
1333         pair: よくある質問と回答; 改行と文字を表示するには?
1334
1335 改行と文字を表示するには?
1336 ==========================
1337
1338 nl 変数で改行します。
1339
1340 .. code-block:: ring
1341
1342         See "Hello" + nl
1343
1344 複数行リテラルでも改行します。
1345
1346 .. code-block:: ring
1347
1348         See "Hello
1349
1350         "
1351
1352 char(nASCII) 関数で他の文字を表示します。
1353
1354 .. code-block:: ring
1355
1356         See char(109) + nl +    # m の表示
1357             char(77)            # M の表示
1358
1359
1360 .. index::
1361         pair: よくある質問と回答; qApp クラス名末尾に () を使用しない理由は?
1362
1363 qApp クラス名末尾に () を使用しない理由は?
1364 ===========================================
1365
1366 RingQt で GUI を作成する場合は、新しいオブジェクトの作成時にクラス名末尾に () を使用します。例えば、
1367
1368 .. code-block:: ring
1369
1370         new qWidget() { setWindowTitle("Hello World") resize(400,400) show() }
1371
1372 この処理の前に、 qApp クラスからオブジェクトを作成しますが、名前の後ろには () を使用しません。
1373
1374 .. code-block:: ring
1375
1376         Load "guilib.ring"
1377         app = new qApp
1378         {
1379             win=new qWidget()
1380             {
1381                 setwindowtitle(:test)
1382                 show()
1383             }
1384             exec()
1385         }
1386
1387 クラス名末尾に () を使うと、クラス内にある init() メソッドの呼び出し、およびこのメソッドへの仮引数を渡す意味になります。
1388
1389 クラス内に init() がないメソッドで () を使うと、例外エラーメッセージになります。
1390
1391 そのほかのクラスには、 init() メソッドはありますが qApp クラスにはありません。
1392 関数を使用したオブジェクトのポインタを返すオブジェクトの作成に必要であり、
1393 このポインタは pObject 属性に格納されるのが理由です。
1394 詳細情報は ring_qt.ring ファイルに収録されているクラスを参照してください。
1395
1396
1397 .. index::
1398         pair: よくある質問と回答; ウィンドウのタイトルバーが画面外に移動してしまう原因は?
1399
1400 ウィンドウのタイトルバーが画面外に移動してしまう原因は?
1401 ========================================================
1402
1403 このコードを記述した場合、
1404
1405
1406 .. code-block:: ring
1407
1408         Load "guilib.ring"
1409         app = new qApp
1410         {
1411                 win=new qWidget()
1412                 {
1413                       setwindowtitle(:test)
1414                       setGeometry(0,0,200,200)
1415                       show()
1416                 }
1417                 exec()
1418         }
1419
1420 ウィンドウが (200,200) の寸法で (0,0) の地点へ移動すると思うでしょう。
1421 実際は、ウィンドウのタイトルバーが画面外に移動してしまいます。
1422
1423 これは Qt フレームワークの挙動と関連があります。
1424
1425 このコードで問題を回避します。
1426
1427 .. code-block:: ring
1428
1429         load "guilib.ring"
1430         new qApp {
1431                 new qWidget() {
1432                         move(0,0)
1433                         resize(200,200)
1434                         show()
1435                 }
1436                 exec()
1437         }
1438
1439
1440 .. index::
1441         pair: よくある質問と回答; GUI アプリケーションでボタンの配列を作成するには?
1442
1443 GUI アプリケーションでボタンの配列を作成するには?
1444 ==================================================
1445
1446 この用例をご確認ください:
1447
1448 .. code-block:: ring
1449
1450         Load "guilib.ring"
1451
1452         App1 = new qApp {
1453
1454                 win1 = new qWidget() {
1455                         move(0,0)
1456                         resize(500,500)
1457                         new qPushButton(win1)
1458                         {
1459                                 settext("OK")
1460                                 setclickevent("click()")
1461                         }
1462                         btn1 = new qPushButton(win1)
1463                         {
1464                                 setgeometry(100,100,100,30)
1465                                 settext("Button1")
1466                         }
1467
1468                         btn2 = new qPushButton(win1)
1469                         {
1470                                 setgeometry(200,100,100,30)
1471                                 settext("Button2")
1472                         }
1473
1474                         button = [btn1, btn2]
1475                         show()
1476                 }
1477
1478                 exec()
1479
1480         }
1481
1482         func click
1483
1484                 button[1] { settext ("Button3") }
1485                 button[2] { settext ("Button4") }
1486
1487
1488 .. index::
1489         pair: よくある質問と回答; ウィンドウを閉じた後に別のウィンドウを表示するには?
1490
1491 ウィンドウを閉じた後に別のウィンドウを表示するには?
1492 ====================================================
1493
1494 この用例は、ウィンドウを閉じる方法と別のウィンドウを表示する方法です。
1495
1496 .. code-block:: none
1497
1498         Load "guilib.ring"
1499
1500         app=new qApp
1501         {
1502                 frmBefore=new Qwidget()
1503                 {
1504                         setWindowTitle("before!")
1505                         resize(300,320)
1506                         move(200,200)
1507
1508                         button=new qPushButton(frmBefore)
1509                         {
1510                                 setText("Close")
1511                                 setClickEvent("frmBefore.close() frmMain.show()")
1512                         }
1513
1514                         show()
1515                 }
1516
1517                 frmMain=new Qwidget()
1518                 {
1519                         setWindowTitle("After!")
1520                         resize(300,320)
1521                         move(200,200)
1522                 }
1523
1524                 exec()
1525
1526         }
1527
1528
1529 .. index::
1530         pair: よくある質問と回答; モーダルウィンドウの作成方法は?
1531
1532 モーダルウィンドウの作成方法は?
1533 ================================
1534
1535 この用例は、モーダルウィンドウの作成方法です。
1536
1537 .. code-block:: ring
1538
1539         load "guilib.ring"
1540         app=new qApp
1541         {
1542                 frmStart=new Qwidget()
1543                 {
1544                         setWindowTitle("The First Window")
1545                         resize(300,320)
1546                         move(200,200)
1547
1548                         button=new qPushButton(frmStart)
1549                         {
1550                                 setText("Show Modal Window")
1551                                 resize(200,30)
1552                                 setClickEvent("frmModal.show()")
1553                         }
1554
1555                         new qPushButton(frmStart)
1556                         {
1557                                 setText("Close Window")
1558                                 move(0,50)
1559                                 resize(200,30)
1560                                 setClickEvent("frmStart.Close()")
1561                         }
1562
1563                         show()
1564                 }
1565
1566                 frmModal =new Qwidget()
1567                 {
1568                         setWindowTitle("Modal Window")
1569                         resize(300,320)
1570                         move(200,200)
1571                         setparent(frmStart)
1572                         setwindowmodality(true)
1573                         setwindowflags(Qt_Dialog)
1574                 }
1575
1576                 exec()
1577
1578         }
1579
1580
1581 関連資料:
1582
1583 * http://doc.qt.io/qt-5/qtwidgets-widgets-windowflags-example.html
1584 * http://doc.qt.io/qt-5/qt.html#WindowType-enum
1585 * http://doc.qt.io/qt-5/qwindow.html#setParent
1586 * http://doc.qt.io/qt-5/qt.html#WindowModality-enum
1587
1588
1589 .. index::
1590         pair: よくある質問と回答; 最大化ボタンの無効化およびウィンドウのサイズを変更するには?
1591
1592 最大化ボタンの無効化およびウィンドウのサイズを変更するには?
1593 ============================================================
1594
1595 setWindowFlags() メソッドを使用します。
1596
1597 .. code-block:: ring
1598
1599         Load "guilib.ring"
1600         app1 = new qapp {
1601                         win1 = new qwidget() {
1602                                         setwindowtitle("First")
1603                                         setgeometry(100,100,500,500)
1604
1605                                         new qpushbutton(win1) {
1606                                                         setgeometry(100,100,100,30)
1607                                                         settext("close")
1608                                                         setclickevent("app1.quit()")
1609                                         }
1610
1611                                         new qpushbutton(win1) {
1612                                                         setgeometry(250,100,100,30)
1613                                                         settext("Second")
1614                                                         setclickevent("second()")
1615                                         }
1616
1617                                         showmaximized()
1618                         }
1619                         exec()
1620         }
1621
1622         func second
1623                         win2 = new qwidget() {
1624                                         setwindowtitle("Second")
1625                                         setgeometry(100,100,500,500)
1626                                         setwindowflags(Qt_dialog)
1627                                         show()
1628                         }
1629
1630
1631 .. index::
1632         pair: よくある質問と回答; ODBC から SQLite を使うには?
1633
1634 ODBC から SQLite を使うには?
1635 =============================
1636
1637 Ring 1.1 以降では SQLite に標準対応しており ODBC は不要です。
1638
1639 また、 RingQt から SQLite へアクセスできます。
1640
1641 質問への回答
1642
1643 .. code-block:: ring
1644
1645         pODBC = odbc_init()
1646         odbc_connect(pODBC,"DRIVER=SQLite3 ODBC Driver;Database=mydb.db;LongNames=0;"+
1647                            "Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
1648         odbc_execute(pODBC,"create table 'tel' ('ID','NAME','PHONE');")
1649         odbc_execute(pODBC,"insert into 'tel' values ('1','Mahmoud','123456');")
1650         odbc_execute(pODBC,"insert into 'tel' values ('2','Ahmed','123456');")
1651         odbc_execute(pODBC,"insert into 'tel' values ('3','Ibrahim','123456');")
1652         odbc_execute(pODBC,"select * from tel") + nl
1653         nMax = odbc_colcount(pODBC)
1654         See "Columns Count : " + nMax + nl
1655         while odbc_fetch(pODBC)
1656                 See nl
1657                 for x = 1 to nMax
1658                         see odbc_getdata(pODBC,x)
1659                         if x != nMax see " - " ok
1660                 next
1661         end
1662         odbc_disconnect(pODBC)
1663         odbc_close(pODBC)
1664
1665 実行結果:
1666
1667 .. code-block:: none
1668
1669         Columns Count : 3
1670
1671         1 - Mahmoud - 123456
1672         2 - Ahmed - 123456
1673         3 - Ibrahim - 123456
1674
1675 このプログラムは、ファイルを作成します : mydb.db
1676
1677 注意 : ODBC ドライバを表示したとき、そこにある長いリストを確認できます。
1678
1679 .. code-block:: none
1680
1681         SQLite3 ODBC Driver - UsageCount=1
1682         SQLite ODBC Driver - UsageCount=1
1683         SQLite ODBC (UTF-8) Driver - UsageCount=1
1684
1685 そして “SQLite3 ODBC Driver” を使用しています。
1686
1687
1688 .. index::
1689         pair: よくある質問と回答; dBase/Harbour データベースへ接続できますか?
1690
1691 dBase/Harbour データベースへ接続できますか?
1692 ============================================
1693
1694 多種多様なデータベースを ODBC で接続できます。
1695
1696 xBase ファイル (\*.DBF) へ接続するには、
1697
1698 .. code-block:: ring
1699
1700         See "Using DBF Files using ODBC" + nl
1701         pODBC = odbc_init()
1702         See "Connect to database" + nl
1703         odbc_connect(pODBC,"Driver={Microsoft dBase Driver (*.dbf)};"+
1704                            "datasource=dBase Files;DriverID=277")
1705         See "Select data" + nl
1706         odbc_execute(pODBC,"select * from tel.dbf")
1707         nMax = odbc_colcount(pODBC)
1708         See "Columns Count : " + nMax + nl
1709         while odbc_fetch(pODBC)
1710                    See "Row data:" + nl
1711                    for x = 1 to nMax
1712                                    see odbc_getdata(pODBC,x) + " - "
1713                    next
1714         end
1715         See "Close database..." + nl
1716         odbc_disconnect(pODBC)
1717         odbc_close(pODBC)
1718
1719 実行結果
1720
1721 .. code-block:: none
1722
1723         Using DBF Files using ODBC
1724         Connect to database
1725         Select data
1726         Columns Count : 3
1727         Row data:
1728         Ahmad - Egypt - 234567 - Row data:
1729         Fady - Egypt - 345678 - Row data:
1730         Shady - Egypt - 456789 - Row data:
1731         Mahmoud - Egypt - 123456 - Close database...
1732
1733
1734 また Visual FoxPro データベースにも接続できます (Visual FoxPro ドライバのインストールが必要です)。
1735
1736 .. code-block:: ring
1737
1738
1739         See "ODBC test 6" + nl
1740         pODBC = odbc_init()
1741         See "Connect to database" + nl
1742         odbc_connect(pODBC,"Driver={Microsoft Visual FoxPro Driver};"+
1743                 "SourceType=DBC;SourceDB=C:\PWCT19\ssbuild\PWCTDATA\CH1\Data\mydata.dbc;")
1744         See "Select data" + nl
1745         see odbc_execute(pODBC,"select * from t38") + nl
1746         nMax = odbc_colcount(pODBC)
1747         See "Columns Count : " + nMax + nl
1748         while odbc_fetch(pODBC)
1749                 See "Row data:" + nl
1750                 for x = 1 to nMax
1751                         see odbc_getdata(pODBC,x) + " - "
1752                 next
1753         end
1754         See "Close database..." + nl
1755         odbc_disconnect(pODBC)
1756         odbc_close(pODBC)
1757
1758
1759 .. index::
1760         pair: よくある質問と回答; setClickEvent() はオブジェクトのメソッドを直接参照しない理由は?
1761
1762 setClickEvent() はオブジェクトのメソッドを直接参照しない理由は?
1763 ================================================================
1764
1765 setClickEvent(cCode) は、コードを有する文字列を受け入れます。 イベントの発生時にコードは実行されます。
1766
1767 Ring は 手続き型、オブジェクト指向、関数型など様々なプログラミングパラダイムに対応しています。
1768
1769 プログラミング言語の水準で様々なパラダイムに対応するときは、二つの選択肢のうち、どちらのパラダイムが使用されるのか検出することはできません。
1770
1771 (1) 各種プログラミングパラダイムで動作する一般的な解決方法があります。
1772
1773 (2) あるパラダイムのうちの一つと合致する各種解決方法があります。
1774
1775 setClickEvent() および、そのほかは (様々なプログラミングパラダイムで動作する一般的な解決方法) に所属しています。
1776
1777 クラスとオブジェクトの取り扱いに関する注意を一切しなくても、文字列のコードを渡すことで実行されます。
1778
1779 このコードは関数の呼び出し、メソッドの呼び出しと変数の値の設定などができました。
1780
1781 そのほかのプログラミング言語では、イベントでオブジェクト指向プログラミングとメソッドの呼び出しの使用を強制します。また、現在のオブジェクトなどの仮引数を取得するために無名関数を使用します。
1782
1783 現在、一般的な解決方法は方法はありますが、将来は、特定のパラダイムと合致する
1784 明確な解決方法を追加する場合があります (オブジェクト指向、宣言型プログラミング、および自然言語プログラミング)。
1785
1786
1787 .. index::
1788         pair: よくある質問と回答; 定義エラーを起こさずに関数を呼び出せる理由は?
1789
1790 定義エラーを起こさずに関数を呼び出せる理由は?
1791 ==============================================
1792
1793 プログラムは次の順序に従います。
1794
1795 (1) ファイルの読み込み
1796 (2) グローバル変数とステートメント
1797 (3) 関数
1798 (4) パッケージ、クラスとメソッド
1799
1800 どのような意味がありますか?
1801
1802 (1) \**** 関数がない場合は、その後はクラスとなります。 \****
1803 (2) \**** 関数、メソッド、クラス、パッケージを終わらせるための命令は不要です。 \****
1804
1805 この用例をご確認ください。
1806
1807 .. code-block:: ring
1808
1809         See "Hello"
1810         test()
1811         func test
1812             see "message from the test function!" + nl
1813         class test
1814
1815 前述の用例では、 test() 関数があるため test() を用いて直接的に呼び出せます。
1816
1817 この用例では、 test() がメソッドになります。
1818
1819 .. code-block:: ring
1820
1821         See "Hello"
1822         test()    # ランタイムエラーメッセージ
1823         class test
1824                 func test # Test() はメソッドです (関数ではない)
1825                         see "message from the test method!" + nl
1826
1827 メソッドの定義後に、関数を直接呼び出そうとしたときはエラーになります。
1828
1829 前述のプログラムは必ずこの通りにしてください。
1830
1831 .. code-block:: ring
1832
1833         See "Hello"
1834         new test { test() }   # メソッドの呼び出し
1835         class test
1836                 func test # Test() はメソッドです (関数ではない)
1837                         see "message from the test method!" + nl
1838
1839
1840 .. index::
1841         pair: よくある質問と回答; RingQt の拡張機能とクラスの追加方法は?
1842
1843 RingQt の拡張機能とクラスの追加方法は?
1844 =======================================
1845
1846 一般に C または C++ のコードで Ring を拡張します。
1847
1848 Ring のコードから C 関数の呼び出し、または C++ クラスとメソッドを使えます。
1849
1850 詳細情報は、本取扱説明書の「C/C++ による拡張機能の開発方法」をご確認ください。
1851
1852 このコードの用例では Ring ライブラリ (\*.lib) を使用して \*.c ファイルを DLL ファイルへコンパイルします。
1853
1854 .. code-block:: c
1855
1856         #include "ring.h"
1857
1858         RING_FUNC(ring_ringlib_dlfunc)
1859         {
1860                 printf("Message from dlfunc");
1861         }
1862
1863         RING_API void ringlib_init(RingState *pRingState)
1864         {
1865                 ring_vm_funcregister("dlfunc",ring_ringlib_dlfunc);
1866         }
1867
1868 Ring は、 LoadLib() 関数で DLL ファイルを読み込んだ後に Ring 関数から dlfunc() 関数が呼び出されます。その後に C 関数を呼び出します。
1869
1870 .. code-block:: ring
1871
1872         See "Dynamic DLL" + NL
1873         LoadLib("ringlib.dll")
1874         dlfunc()
1875
1876 実行結果:
1877
1878 .. code-block:: none
1879
1880         Dynamic DLL
1881         Message from dlfunc
1882
1883 取扱説明書を読むと、仮引数 (文字列、数値、リストとオブジェクト) などの取得方法について知ることができます。
1884
1885 また、関数から値 (任意型) を返す方法も知ることができます。
1886
1887 実体験ですが、 C ライブラリまたは C++ ライブラリへ対応作業をしているとき、
1888
1889 ほとんどの関数で、ほとんどのコードを共有していることを発見しました。
1890
1891 こちらのコード生成器を使うと Ring 用の C/C++ ライブラリのラッパーを手軽に生成でき、時間の節約になります。
1892
1893 https://github.com/ring-lang/ring/blob/master/extensions/codegen/parsec.ring
1894
1895 コード生成器は 1200 行以下の Ring プログラムです。
1896
1897 コード生成器で入力した設定ファイルには C/C++ ライブラリの情報があります。
1898
1899 関数プロトタイプ、クラスとメソッド、定数、列挙体、構造体とメンバなど。
1900
1901 そして、コード生成器で生成します。
1902
1903 * C ライブラリに関する \*.C ファイル (ライブラリ関数を使用可能)
1904
1905 * C++ ライブラリに関する \*.CPP ファイル (C++ クラスとメソッドを使用可能)
1906
1907 * \*.Ring ファイル (C++ のクラスを Ring のクラスとして使用可能)
1908
1909 * \*.RH ファイル (定数)
1910
1911 コード生成器の動作を理解するには、この Allegro ゲームプログラミング・ライブラリ用の拡張機能をご確認ください。
1912
1913 https://github.com/ring-lang/ring/tree/master/extensions/ringallegro
1914
1915 ひとつ目の設定ファイルは、
1916
1917 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/allegro.cf
1918
1919 このファイルは Allegro の取扱説明書と Ring コード生成器の規則を用いて記述しました。
1920
1921 このバッチファイルでコード生成器を実行します。
1922
1923 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/gencode.bat
1924
1925 または、このスクリプトを使用します。
1926
1927 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/gencode.sh
1928
1929 生成されたソースコードファイルを取得します。
1930
1931 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/ring_allegro.c
1932
1933 生成されたソースコードファイル (ring_allegro.c) は約 1,2000 行です。
1934
1935 ですが、設定ファイルは 1000 行以下です。
1936
1937 ライブラリをビルドするには (DLL ファイルの作成)
1938
1939 https://github.com/ring-lang/ring/blob/master/extensions/ringallegro/buildvc.bat
1940
1941 また、この拡張機能は LibSDL ライブラリに関して確認できます。
1942
1943 https://github.com/ring-lang/ring/tree/master/extensions/ringsdl
1944
1945 まとめとして、知っておく必要のある関連事項は
1946
1947 1 - 設定ファイルの記述
1948
1949 2 - コード生成器の使用
1950
1951 3 - ライブラリや拡張機能の作成
1952
1953 4 - Ring コードからライブラリや拡張機能を使用
1954
1955 さて Qt についての質問へ移りましょう。
1956
1957 RingQt は Ringの拡張機能です (ringqt.dll)。
1958
1959 Ring の改修や変更は不要です。
1960
1961 (1) RingQt の変更が必要です。
1962
1963 (2) または、別の Qt ベースの拡張機能により、 Ring の機能を拡張します (だだし、同じ Qt バージョンです)。
1964
1965 最初の選択肢に関しては RingQt を参照してください。
1966
1967 https://github.com/ring-lang/ring/tree/master/extensions/ringqt
1968
1969 設定ファイル
1970
1971 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/qt.cf
1972
1973 ソースコードを生成するには
1974
1975 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/gencode.bat
1976
1977 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/gencode.sh
1978
1979 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/gencodeandroid.bat
1980
1981 DLL/so/Dylib ファイルをビルドするには
1982
1983 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/buildmingw32.bat
1984
1985 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/buildgcc.sh
1986
1987 https://github.com/ring-lang/ring/blob/master/extensions/ringqt/buildclang.sh
1988
1989 RingQt の学習をしてください。
1990
1991 利用できる選択肢について学んでください。
1992
1993 (1) 直接 Qt のクラスを接続します。
1994
1995 (2) 新しい自作クラスを接続するために新しいクラスを作成します。
1996
1997 第二の選択肢は (前述の二つの要点、またはそれ以前にある2つの要点)、
1998
1999 C++ コードによる新しいクラスを作成します。
2000
2001 そして、作成したクラスを RingQt へ統合、または特別な DLL を用意します (判断に応じて)。
2002
2003 一般的な動作ならば、 RingQt に記述してください (他の人の手助けになります)。
2004
2005 特別な動作ならば、別の拡張機能に記述してください (特定のアプリケーション)。
2006
2007
2008 .. index::
2009         pair: よくある質問と回答; Combobox および QTableWidget のセルへ他の要素を追加するには?
2010
2011 Combobox および QTableWidget のセルへ他の要素を追加するには?
2012 =============================================================
2013
2014 このコードをご確認ください。
2015
2016 .. code-block:: ring
2017
2018         Load "guilib.ring"
2019         New qApp
2020         {
2021                 win1 = new qMainWindow() {
2022                         setGeometry(100,100,1100,370)
2023                         setwindowtitle("Using QTableWidget")
2024
2025                         Table1 = new qTableWidget(win1) {
2026                                 setrowcount(10) setcolumncount(10)
2027                                 setGeometry(0,0,800,400)
2028                                 setselectionbehavior(QAbstractItemView_SelectRows)
2029
2030                                 for x = 1 to 10
2031                                         for y = 1 to 10
2032                                                 item1 = new qtablewidgetitem("R"+X+"C"+Y)
2033                                                 setitem(x-1,y-1, item1)
2034                                         next
2035                                 next
2036
2037                                 cmb = new QComboBox(Table1) {
2038                                         alist = ["one","two","three","four","five"]
2039                                         for x in aList additem(x,0) next
2040                                 }
2041                                         setCellWidget(5, 5, cmb)
2042                         }
2043
2044                         setcentralwidget(table1)
2045                         show()
2046                 }
2047                 exec()
2048         }
2049
2050
2051 .. index::
2052         pair: よくある質問と回答; QTableWidget で選択されたセルの内容に処理を行うには?
2053
2054 QTableWidget で選択されたセルの内容に処理を行うには?
2055 =====================================================
2056
2057 このサンプルをご確認ください。
2058
2059 .. code-block:: ring
2060
2061         Load "guilib.ring"
2062
2063         New qApp {
2064                 win1 = new qMainWindow() {
2065                         setGeometry(100,100,800,600)
2066                         setwindowtitle("Using QTableWidget")
2067                         Table1 = new qTableWidget(win1) {
2068                                 setrowcount(10) setcolumncount(10)
2069                                 setGeometry(10,10,400,400)
2070                                 for x = 1 to 10
2071                                         for y = 1 to 10
2072                                                 item1 = new qtablewidgetitem("10")
2073                                                 setitem(x-1,y-1,item1)
2074                                         next
2075                                 next
2076                         }
2077                         btn1 = new qPushButton(win1) {
2078                                 setText("Increase")
2079                                 setGeometry(510,10,100,30)
2080                                 setClickEvent("pClick()")
2081                         }
2082                         show()
2083                 }
2084                 exec()
2085         }
2086
2087         func pClick
2088                 for nRow = 0 to Table1.rowcount() - 1
2089                         for nCol = 0 to Table1.columncount() - 1
2090                                 Table1.item(nRow,nCol)  {
2091                                         if isSelected()
2092                                                 setText( "" + ( 10 + text()) )
2093                                         ok
2094                                 }
2095                         next
2096                 next
2097
2098
2099 .. index::
2100         pair: よくある質問と回答; 三種類の記法のうち一般に使用されている、またはコミュニティで推薦されているものは?
2101
2102 三種類の記法のうち一般に使用されている、またはコミュニティで推薦されているものは?
2103 ==================================================================================
2104
2105 (1) 記法を選択するだけですが、同じプロジェクトで異なる記法の併用、
2106      または最低でも、同じコンテキストを併用しないでください (実装、テスト、スクリプトなど)。
2107
2108 .. note:: プロジェクトの開始時に規則の明示、およびその規則に従ってください。
2109
2110 (2) 記法の自作ができます (キーワードの変更により) - この考えはカスタマイズと自由のためのものです。
2111
2112 .. note:: 自然言語を使用する場合など、明確な理由がある場合に限り、新しい記法の作成とキーワードの変更を行うほうが良いです (日本語、アラビア語、フランス語など)。
2113
2114 (3) 第一形式は質問、チュートリアル、および小規模アプリケーション・プログラム (5,000行以下のコード) には最適です (筆者個人の意見です)。
2115       用例 : Ring 取扱説明書、 Ring のサンプル、およびアプリケーションの大部分
2116
2117 (4) 第三形式は大規模アプリケーション、および現役プログラマには最適です (筆者個人の意見です)。
2118
2119         用例 (フォームデザイナー) : https://github.com/ring-lang/ring/tree/master/applications/formdesigner