OSDN Git Service

...。
[ring-lang-081/ring.git] / docs / ja-jp / build / html / _sources / ringemb.txt
1 .. index:: 
2         single: Ring へ Ring を組み込むには; はじめに
3
4 ===========================
5 Ring へ Ring を組み込むには
6 ===========================
7
8 Ring プログラム、またはアプリケーションへ Ring を組み込む方法を学びます。
9
10 .. index:: 
11         pair: Ring へ Ring を組み込むには; ステートを共有せずに Ring へ Ring を組み込むには
12
13 ステートを共有せずに Ring へ Ring を組み込むには
14 ================================================
15
16 Ring 1.0 より Ring を C へ組み込むための関数は実装されていました。
17 また eval() 関数で Ring プログラム内で Ring のコードを実行できます。
18 この公開版では、ステートを共有せずに Ring を Ring プログラムへ組み込むための関数があります。
19
20 利点:
21
22 (1) Ring プログラムとアプリケーションの統合で競合が発生しません。
23
24 (2) Ring のコードを安全な環境で実行して、トレースを行えます。
25
26 用例:
27
28 .. code-block:: ring
29
30         pState = ring_state_init()
31         ring_state_runcode(pState,"See 'Hello, World!'+nl")
32         ring_state_runcode(pState,"x = 10")
33
34         pState2 = ring_state_init()
35         ring_state_runcode(pState2,"See 'Hello, World!'+nl")
36         ring_state_runcode(pState2,"x = 20")
37
38         ring_state_runcode(pState,"see x +nl")
39         ring_state_runcode(pState2,"see x +nl")
40
41         v1 = ring_state_findvar(pState,"x")
42         v2 = ring_state_findvar(pState2,"x")
43
44         see v1[3] + nl
45         see V2[3] + nl
46
47         ring_state_delete(pState)
48         ring_state_delete(pState2)
49
50 実行結果:
51
52 .. code-block:: ring
53
54         Hello, World!
55         Hello, World!
56         10
57         20
58         10
59         20
60
61 .. index:: 
62         pair: Ring へ Ring を組み込むには; プログラムの直列実行
63
64 プログラムの直列実行
65 ====================
66
67 ring_state_main() 関数はアプリケーションの実行後に、別のアプリケーションを実行します。
68
69 用例:
70
71 .. code-block:: ring
72
73         chdir(exefolder()+"/../applications/formdesigner")
74         ring_state_main('formdesigner.ring')
75         chdir(exefolder()+"/../applications/cards")
76         ring_state_main('cards.ring')
77
78 .. index:: 
79         pair: Ring へ Ring を組み込むには; ring_state_setvar()
80
81 ring_state_setvar()
82 ===================
83
84 ring_state_setvar() 関数は変数の値を設定します。
85
86 値には「文字列、数値、リスト、または C ポインタ」を指定します。
87
88 この関数は下位 Ring 環境へリストとC ポインタを手早く渡すために必要です。
89
90 文法:
91
92 .. code-block:: none
93
94         ring_state_setvar(oState,cVariableName,Value)
95
96 用例:
97
98 .. code-block:: ring
99
100         load "guilib.ring"
101
102         myapp   = null
103         win     = null
104
105         func main
106                 myapp = new qApp {
107                         win = new qWidget() {
108                                 setWindowTitle("Advanced Example on using ring_state_setvar()")
109                                 move(100,100)
110                                 resize(600,400)
111                                 new qPushButton(win) {
112                                         setText("Test")
113                                         setClickEvent("Test()")
114                                 }
115                                 # Qt でタイマーの作成とウィンドウを閉じる動作を行います。
116                                 # これだけでウィンドウを閉じるには不十分です。
117                                 # このために下位環境では load 'guilib.ring' を
118                                 # 必ず使用してください。
119                                 oFilter = new qAllEvents(win)
120                                 oFilter.setCloseEvent("myapp.quit()")
121                                 win.installeventfilter(oFilter)
122                                 show()
123                         }
124                         exec()
125                 }
126
127         func test
128                 pState = ring_state_init()
129                 ring_state_runcode(pstate,"load 'guilib.ring'")
130                 ring_state_runcode(pState,"x = NULL")
131                 # 文字列を渡します。
132                         ring_state_setvar(pState,"x","hello")
133                         ring_state_runcode(pState,"? x")
134                 # 数値を渡します。
135                         ring_state_setvar(pState,"x",100)
136                         ring_state_runcode(pState,"? x")
137                 # Pass List
138                         ring_state_setvar(pState,"x",["one","two","three"])
139                         ring_state_runcode(pState,"? x")
140                 # リストを渡します。
141                 # Ring オブジェクトを渡すことはできません (win)。
142                 # 理由としてオブジェクトはクラス情報のポインタとして格納されているからです。
143                 # またクラスは Ring の親環境と関連付けられています。
144                 # しかし、下位 Ring 環境にはアクセスできません。
145                 # ですが win.pObject のようにすれば C ポインタを渡せます。
146                         ring_state_setvar(pState,"x",win.pObject)
147                 # さて、オブジェクトを再作成しましたが同じ C ポインタを使用しています。
148                 # したがって親 Ring 環境にある同じウィンドウへアクセスできます。
149                         ring_state_runcode(pState,"
150                                 new qWidget {
151                                         pObject = x
152                                         setwindowtitle('Message from the Sub Ring Environment')
153                                 }
154                         ")
155                 ring_state_delete(pState)
156
157
158 .. index:: 
159         pair: Ring へ Ring を組み込むには; ring_state_new() と ring_state_mainfile() 関数
160
161 ring_state_new() と ring_state_mainfile() 関数
162 ==============================================
163
164 ring_state_new() と ring_state_mainfile() 関数は Ring プログラムから別の Ring プログラムを実行します。
165
166 ring_state_main() 関数とは異なり、こちらは Ring ステートの削除時に制御できます!
167
168 これは GUI プログラムから別の GUI プログラムを実行するときに重要です。
169
170 この場合の理由は GUI ライブラリ (RingQt) を共有しており、
171
172 呼び出し元は qApp.Exec() を呼び出すからです。
173
174 よって、下位プログラムを停止せずにメインプログラムへ戻ります。
175
176 ここで下位プログラムのステートを削除してしまうと、下位プログラムのイベント実行時に問題が発生します。
177
178 ステートを保持することは、下位 GUI プログラムの収容先となっている GUI プログラムでは重要です。
179
180 用例:
181
182 .. code-block:: ring
183
184         load "guilib.ring"
185
186         func main
187                 new qApp {
188                         win = new qWidget() {
189                                 setWindowTitle("Test ring_state_mainfile()")
190                                 resize(400,400) move(100,100)
191                                 btn = new qPushButton(Win) {
192                                         settext("test")
193                                         setclickevent("mytest()")
194                                 }
195                                 show()
196                         }
197                         exec()
198                 }
199
200         func mytest
201                 pState = ring_state_new()
202                 ring_state_mainfile(pState,"runprogram.ring")
203                 # ここで GUI アプリケーションを実行する場合はステートを削除しないでください。
204                 # なお GUI アプリケーションのイベントを実行できます。
205                         // ring_state_delete(pState)
206
207 この機能を使用する場合は、前述の用例を基にアプリケーションで必要な更新をすることを覚えておいてください。
208
209 この時点で ring_state_delete() 関数を呼び出すとメモリリークを回避できます!
210
211
212 .. index:: 
213         pair: Ring へ Ring を組み込むには; Ring へ Ring を組み込んだときのランタイムエラーについて
214
215 Ring へ Ring を組み込んだときのランタイムエラーについて
216 =======================================================
217
218 Ring 1.8 から Ring へ Ring を組み込んだときに、
219
220 ゲスト環境でエラーが発生してもホストは異常終了しなくなりました。
221
222 用例:
223
224 .. code-block:: ring
225
226         ? "Start the test!" 
227
228         pState = ring_state_init()
229
230         ring_state_runcode(pState," ? 'Let us try having an error' ? x")
231
232         ring_state_delete(pState)
233
234         ? ""
235         ? "End of test!"
236
237 実行結果:
238
239 .. code-block:: none
240
241         Start the test!
242         Let us try having an error
243
244         Line 1 Error (R24) : Using uninitialized variable : x
245         in file Ring_EmbeddedCode
246         End of test!
247
248 .. index:: 
249         pair: Ring へ Ring を組み込むには; ring_state_filetokens() 関数
250
251 ring_state_filetokens() 関数
252 ============================
253
254 Ring 1.12 では ring_state_filetokens() 関数に対応しました。
255
256 ring_state_filetokens() 関数は Ring ソースコードファイルにあるトークンを一括取得します。
257
258 .. code-block:: ring
259
260         C_FILENAME      = "test_tokens.ring"
261         C_WIDTH         = 12
262
263         # ファイルの書き込み
264                 write(C_FILENAME,'
265                                 see "Hello, World!"
266                                 ? 3*2+3
267                                 Name = "Ring"
268                                 ? Name
269         ')
270
271         # トークンの種類
272                 C_KEYWORD       = 0
273                 C_OPERATOR      = 1
274                 C_LITERAL       = 2
275                 C_NUMBER        = 3
276                 C_IDENTIFIER    = 4
277                 C_ENDLINE       = 5
278
279         # キーワードリスト
280         aKEYWORDS = ["IF","TO","OR","AND","NOT","FOR","NEW","FUNC", 
281         "FROM","NEXT","LOAD","ELSE","SEE","WHILE","OK","CLASS","RETURN","BUT", 
282         "END","GIVE","BYE","EXIT","TRY","CATCH","DONE","SWITCH","ON","OTHER","OFF", 
283         "IN","LOOP","PACKAGE","IMPORT","PRIVATE","STEP","DO","AGAIN","CALL","ELSEIF", 
284         "PUT","GET","CASE","DEF","ENDFUNC","ENDCLASS","ENDPACKAGE", 
285         "CHANGERINGKEYWORD","CHANGERINGOPERATOR","LOADSYNTAX"]
286
287         pState = ring_state_new()
288         aList = ring_state_filetokens(pState,C_FILENAME)
289         PrintTokens(aList)
290         ring_state_delete(pState)
291
292         func PrintTokens aList
293                 for aToken in aList
294                         switch aToken[1]
295                         on C_KEYWORD 
296                                 ? Width("Keyword",C_WIDTH) + ": "  + aKeywords[0+aToken[2]]
297                         on C_OPERATOR 
298                                 ? Width("Operator",C_WIDTH)  + ": " + aToken[2]
299                         on C_LITERAL 
300                                 ? Width("Literal",C_WIDTH)  + ": " + aToken[2]
301                         on C_NUMBER 
302                                 ? Width("Number",C_WIDTH)  + ": " + aToken[2]
303                         on C_IDENTIFIER 
304                                 ? Width("Identifier",C_WIDTH)  + ": " + aToken[2]
305                         on C_ENDLINE 
306                                 ? "EndLine"
307                         other
308                                 
309                         off
310                 next
311
312         func Width cText,nWidth
313                 return cText+copy(" ",nWidth-len(cText))
314
315 実行結果:
316
317 .. code-block:: none
318
319         EndLine
320         Keyword     : SEE
321         Literal     : Hello, World!
322         EndLine
323         Operator    : ?
324         Number      : 3
325         Operator    : *
326         Number      : 2
327         Operator    : +
328         Number      : 3
329         EndLine
330         Identifier  : name
331         Operator    : =
332         Literal     : Ring
333         EndLine
334         Operator    : ?
335         Identifier  : name
336         EndLine