2 single: Ring へ Ring を組み込むには; はじめに
4 ===========================
6 ===========================
8 Ring プログラム、またはアプリケーションへ Ring を組み込む方法を学びます。
11 pair: Ring へ Ring を組み込むには; ステートを共有せずに Ring へ Ring を組み込むには
13 ステートを共有せずに Ring へ Ring を組み込むには
14 ================================================
16 Ring 1.0 より Ring を C へ組み込むための関数は実装されていました。
17 また eval() 関数で Ring プログラム内で Ring のコードを実行できます。
18 この公開版では、ステートを共有せずに Ring を Ring プログラムへ組み込むための関数があります。
22 (1) Ring プログラムとアプリケーションの統合で競合が発生しません。
24 (2) Ring のコードを安全な環境で実行して、トレースを行えます。
30 pState = ring_state_init()
31 ring_state_runcode(pState,"See 'Hello, World!'+nl")
32 ring_state_runcode(pState,"x = 10")
34 pState2 = ring_state_init()
35 ring_state_runcode(pState2,"See 'Hello, World!'+nl")
36 ring_state_runcode(pState2,"x = 20")
38 ring_state_runcode(pState,"see x +nl")
39 ring_state_runcode(pState2,"see x +nl")
41 v1 = ring_state_findvar(pState,"x")
42 v2 = ring_state_findvar(pState2,"x")
47 ring_state_delete(pState)
48 ring_state_delete(pState2)
62 pair: Ring へ Ring を組み込むには; プログラムの直列実行
67 ring_state_main() 関数はアプリケーションの実行後に、別のアプリケーションを実行します。
73 chdir(exefolder()+"/../applications/formdesigner")
74 ring_state_main('formdesigner.ring')
75 chdir(exefolder()+"/../applications/cards")
76 ring_state_main('cards.ring')
79 pair: Ring へ Ring を組み込むには; ring_state_setvar()
84 ring_state_setvar() 関数は変数の値を設定します。
86 値には「文字列、数値、リスト、または C ポインタ」を指定します。
88 この関数は下位 Ring 環境へリストとC ポインタを手早く渡すために必要です。
94 ring_state_setvar(oState,cVariableName,Value)
107 win = new qWidget() {
108 setWindowTitle("Advanced Example on using ring_state_setvar()")
111 new qPushButton(win) {
113 setClickEvent("Test()")
115 # Qt でタイマーの作成とウィンドウを閉じる動作を行います。
116 # これだけでウィンドウを閉じるには不十分です。
117 # このために下位環境では load 'guilib.ring' を
119 oFilter = new qAllEvents(win)
120 oFilter.setCloseEvent("myapp.quit()")
121 win.installeventfilter(oFilter)
128 pState = ring_state_init()
129 ring_state_runcode(pstate,"load 'guilib.ring'")
130 ring_state_runcode(pState,"x = NULL")
132 ring_state_setvar(pState,"x","hello")
133 ring_state_runcode(pState,"? x")
135 ring_state_setvar(pState,"x",100)
136 ring_state_runcode(pState,"? x")
138 ring_state_setvar(pState,"x",["one","two","three"])
139 ring_state_runcode(pState,"? x")
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,"
152 setwindowtitle('Message from the Sub Ring Environment')
155 ring_state_delete(pState)
159 pair: Ring へ Ring を組み込むには; ring_state_new() と ring_state_mainfile() 関数
161 ring_state_new() と ring_state_mainfile() 関数
162 ==============================================
164 ring_state_new() と ring_state_mainfile() 関数は Ring プログラムから別の Ring プログラムを実行します。
166 ring_state_main() 関数とは異なり、こちらは Ring ステートの削除時に制御できます!
168 これは GUI プログラムから別の GUI プログラムを実行するときに重要です。
170 この場合の理由は GUI ライブラリ (RingQt) を共有しており、
172 呼び出し元は qApp.Exec() を呼び出すからです。
174 よって、下位プログラムを停止せずにメインプログラムへ戻ります。
176 ここで下位プログラムのステートを削除してしまうと、下位プログラムのイベント実行時に問題が発生します。
178 ステートを保持することは、下位 GUI プログラムの収容先となっている GUI プログラムでは重要です。
188 win = new qWidget() {
189 setWindowTitle("Test ring_state_mainfile()")
190 resize(400,400) move(100,100)
191 btn = new qPushButton(Win) {
193 setclickevent("mytest()")
201 pState = ring_state_new()
202 ring_state_mainfile(pState,"runprogram.ring")
203 # ここで GUI アプリケーションを実行する場合はステートを削除しないでください。
204 # なお GUI アプリケーションのイベントを実行できます。
205 // ring_state_delete(pState)
207 この機能を使用する場合は、前述の用例を基にアプリケーションで必要な更新をすることを覚えておいてください。
209 この時点で ring_state_delete() 関数を呼び出すとメモリリークを回避できます!
213 pair: Ring へ Ring を組み込むには; Ring へ Ring を組み込んだときのランタイムエラーについて
215 Ring へ Ring を組み込んだときのランタイムエラーについて
216 =======================================================
218 Ring 1.8 から Ring へ Ring を組み込んだときに、
220 ゲスト環境でエラーが発生してもホストは異常終了しなくなりました。
228 pState = ring_state_init()
230 ring_state_runcode(pState," ? 'Let us try having an error' ? x")
232 ring_state_delete(pState)
242 Let us try having an error
244 Line 1 Error (R24) : Using uninitialized variable : x
245 in file Ring_EmbeddedCode
249 pair: Ring へ Ring を組み込むには; ring_state_filetokens() 関数
251 ring_state_filetokens() 関数
252 ============================
254 Ring 1.12 では ring_state_filetokens() 関数に対応しました。
256 ring_state_filetokens() 関数は Ring ソースコードファイルにあるトークンを一括取得します。
260 C_FILENAME = "test_tokens.ring"
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"]
287 pState = ring_state_new()
288 aList = ring_state_filetokens(pState,C_FILENAME)
290 ring_state_delete(pState)
292 func PrintTokens aList
296 ? Width("Keyword",C_WIDTH) + ": " + aKeywords[0+aToken[2]]
298 ? Width("Operator",C_WIDTH) + ": " + aToken[2]
300 ? Width("Literal",C_WIDTH) + ": " + aToken[2]
302 ? Width("Number",C_WIDTH) + ": " + aToken[2]
304 ? Width("Identifier",C_WIDTH) + ": " + aToken[2]
312 func Width cText,nWidth
313 return cText+copy(" ",nWidth-len(cText))
321 Literal : Hello, World!