Ring 1.7 の変更履歴¶
Ring 1.7 (2018年01月25日) の新機能と変更点です。
新機能と変更リスト¶
Ring 1.7 の新機能!
新しい命令: Load Package
ringvm_see() と ringvm_give() 関数
ring_state_new() と ring_state_mainfile() 関数
トレースライブラリの改善
Ring ノートパッドの改善
RingQt の改善
Ring2EXE の改善
RingZip の改善
取扱説明書の改訂
Ring VM の改善
RingLibuv 拡張機能
新しい命令: Load Package¶
‘Load’ 命令により、複数の Ring ソースファイルを同じプロジェクトで使えます。
しかし、これらのファイルでは同じグローバルスコープを共有しています。
さて、 “Load Package” 命令もあります。
“Load Package” では新しいグローバルスコープへライブラリ (*.ring ファイル) を読み込むことができます。
グローバル変数との名前衝突回避となるため、ライブラリの作成時は非常に便利です。
用例:
ファイル: loadpackage.ring
x = 100
? "Hello, World!"
load package "testloadpackage.ring"
? x
test()
ファイル: testloadpackage.ring
? "Hello from testloadpackage.ring"
x = 1000
test()
func test
? x
実行結果:
Hello, World!
Hello from testloadpackage.ring
1000
100
1000
ringvm_see() と ringvm_give() 関数¶
ringvm_see() 関数で See 命令の挙動を変更します。
また ring_see() 関数で元の挙動を使用します。
用例:
see "Hello world" + nl
see 123 + nl
see ["one","two","three"]
see new point {x=10 y=20 z=30}
func ringvm_see t
ring_see("We want to print: ")
ring_See(t)
class point x y z
実行結果:
We want to print: Hello world
We want to print: 123
We want to print: one
two
three
We want to print: x: 10.000000
y: 20.000000
z: 30.000000
ringvm_give() 関数は Give 命令の挙動を変更します。
また、 ring_give() 関数は元の挙動を使用します。
用例:
see "Name: " give name
see "Hello " + name
func ringvm_give
see "Mahmoud" + nl
return "Mahmoud"
実行結果:
Name: Mahmoud
Hello Mahmoud
ring_state_new() と ring_state_mainfile() 関数¶
ring_state_new() と ring_state_mainfile() 関数は Ring プログラムから別の Ring プログラムを実行します。
ring_state_main() 関数とは異なり、こちらは Ring ステートの削除時に制御できます!
これは GUI プログラムから別の GUI プログラムを実行するときに重要です。
この場合は GUI ライブラリ (RingQt) を共有しており、
呼び出し元は qApp.Exec() を呼び出すからです。
よって、下位プログラムを停止せずにメインプログラムへ戻ります。
ここで下位プログラムのステートを削除してしまうと、下位プログラムのイベント実行時に問題が発生します。
ステートを保持することは、下位 GUI プログラムの収容先となっている GUI プログラムでは重要です。
トレースライブラリの改善¶
トレースライブラリの更新により、デバッガのブレークポイントで “callstack” 命令を利用できるようになりました。
この命令は関数のコールスタックを表示します。
用例:
load "tracelib.ring"
func main
? "Hello from main!"
test1()
func test1
? "Hello from test1!"
test2()
func test2
? "Hello from test2!"
test3()
func test3
? "Hello from test3!"
breakpoint()

Ring ノートパッドの改善¶
Ring ノートパッドを更新しました。
拡張子 *.cf への対応
ハッシュ関数 (SHA256) 使用時の改善 - “Save Changes?” (変更を保存しますか?) メッセージ
Ring ノートパッド - ×ボタン - Saving Changes? で問い合わせるようになりました。
RingQt の改善¶
このクラスを RingQt へ追加しました。
QStackedWidget
QCalendarWidget
QOpenGLFunctions
QOpenGLContext
QSurfaceFormat
QOpenGLWidget
QOpenGLVersionProfile
QOpenGLFunctions_3_2_Core
QVector2D
QVector3D
QVector4D
QQuaternion
QMatrix4x4
QOpenGLPaintDevice
QPaintDevice
QOpenGLTimerQuery
QOpenGLDebugLogger
QOpenGLFramebufferObject
QOpenGLVertexArrayObject
QOpenGLBuffer
QOpenGLShaderProgram
QOpenGLShader
QOpenGLTexture
Ring2EXE の改善¶
C/C++ コンパイラがないとき、想定された動作を行うために Ring2EXE を更新しました。
これにより、アプリケーションの配布に適したものを生成できます (exe ファイルと ring ファイル)。
RingZip の改善¶
このライブラリの更新により、サブフォルダにあるファイルの展開に対応しました!
取扱説明書の改訂¶
RingQt クラスの章 - クラスリストの並べ替えを行いました。
Ring VM の改善¶
エラーメッセージの改善
List2Str() 関数で数値を有するリストに対応
分離記号 _ のある数値の対応を修正
変数を使用せずにリストを作成 (ステートメント –> 式 –> リスト)
isNULL() - 英数大小文字同一視 - Null および null は NULL と同等に扱われます。
このオブジェクトで属性に Self オブジェクトの追加へ対応
‘:’ 演算子を使用後に小文字リテラルのキーワードを作成
オブジェクトの表示 - decimals() 関数の考慮
定数を閉られていない場合 - 定数の始点を決定
リストのあるオブジェクトの表示時におけるエラーメッセージの改善
VarPtr() - ローカルスコープにある変数のポインタの取得に対応
新しいスレッドの作成時に perfomance 命令を normal 命令へ交換
RingLibuv 拡張機能¶
Ring 1.7 から RingLibuv 拡張機能を利用できるようなりました。
Libuv は非同期 I/O に主眼を置いたマルチプラットフォーム対応ライブラリです。
用例 (イベントループ):
load "libuv.ring"
counter = 0
idler = NULL
func main
idler = new_uv_idle_t()
uv_idle_init(uv_default_loop(), idler)
uv_idle_start(idler, "wait()")
? "Idling..."
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop());
destroy_uv_idle_t(idler)
func wait
counter++
if counter >= 100000
uv_idle_stop(idler)
ok
実行結果:
Idling...
用例 (サーバー):
load "libuv.ring"
load "objectslib.ring"
? "Testing RingLibuv - Server Side - Using Classes"
open_object(:MyServer)
class MyServer from ObjectControllerParent
DEFAULT_PORT = 13370
DEFAULT_BACKLOG = 1024
addr = new_sockaddr_in()
server = NULL
client = NULL
myloop = NULL
func start
myloop = uv_default_loop()
server = new_uv_tcp_t()
uv_tcp_init(myloop, server)
uv_ip4_addr("127.0.0.1", DEFAULT_PORT, addr)
uv_tcp_bind(server, addr, 0)
r = uv_listen(server, DEFAULT_BACKLOG, Method(:newconnection) )
if r
? "Listen error " + uv_strerror(r)
return 1
ok
uv_run(myloop, UV_RUN_DEFAULT)
destroy_uv_tcp_t(server)
destroy_uv_sockaddr_in(addr)
func newconnection
? "New Connection"
aPara = uv_Eventpara(server,:connect)
nStatus = aPara[2]
if nStatus < 0
? "New connection error : " + nStatus
return
ok
client = new_uv_tcp_t()
uv_tcp_init(myloop, client)
if uv_accept(server, client) = 0
uv_read_start(client, uv_myalloccallback(),
Method(:echo_read))
ok
func echo_read
aPara = uv_Eventpara(client,:read)
nRead = aPara[2]
buf = aPara[3]
if nRead > 0
req = new_uv_write_t()
wrbuf = uv_buf_init(get_uv_buf_t_base(buf), nread)
uv_write(req, client, wrbuf, 1, Method(:echo_write))
? uv_buf2str(wrbuf)
message = "message from the server to the client"
buf = new_uv_buf_t()
set_uv_buf_t_len(buf,len(message))
set_uv_buf_t_base(buf,varptr("message","char *"))
uv_write(req, client, buf, 1, Method(:echo_write))
ok
func echo_write
aPara = uv_Eventpara(client,:read)
req = aPara[1]
実行結果:
クライアントを実行すると、 “New Connection” メッセージが表示されます。
そして “hello from the client” メッセージが表示されます。
Testing RingLibuv - Server Side - Using Classes
New Connection
hello from the client
用例 (スレッドの使用):
load "libuv.ring"
load "objectslib.ring"
? "Testing RingLibuv - Threads - Using Classes"
open_object(:MyThreads)
class MyThreads from ObjectControllerParent
func Start
one_id = new_uv_thread_t()
two_id = new_uv_thread_t()
uv_thread_create(one_id, Method(:One))
uv_thread_create(two_id, Method(:Two))
uv_thread_join(one_id)
uv_thread_join(two_id)
destroy_uv_thread_t(one_id)
destroy_uv_thread_t(two_id)
func one
? "Message from the First Thread!"
func Two
? "Message from the Second Thread!"
実行結果:
Testing RingLibuv - Threads - Using Classes
Message from the First Thread!
Message from the Second Thread!
この拡張機能 (RingLibuv) の詳細は「RingLibuv の用法」を参照してください。