Rubyを軽量化、組み込み向けとして開発された「mruby(軽量Ruby)」が今、IoTでの開発言語として注目されています。Cに比べてコード量を1/4まで低減するmrubyについて、この連載では“mrubyはIoTでこう使え”までを分かりやすく解説します。
2020年には500億のデバイスがインターネットにつながると言われる中で、これらを用いた新しいサービス、新しいビジネスの総称として用いられるのが「Internet of Things(IoT)」です。IoTの普及によってネットワークを利用したさまざまなアイデアや製品が姿を現し、人々に利用されていくでしょう。
歯医者につながった電動歯ブラシ、お天気サイトに連動するスプリンクラー、ゴミが満タンになったらお知らせメールが飛ぶ公園のゴミ箱といった日常的なものから、最適な飛行パターンを解析し燃料削減や飛行時間短縮に貢献するセンサー付飛行機など、ありとあらゆるものにIoTの新しいサービスが応用されはじめています。
IoTのサービスと製品は「新しい組み込み開発」であり、ハードウェア開発者とソフトウェア開発者、それぞれが双方を扱わなくていけません。スピード感のある開発が必要ですし、機能・サービスを向上させるために試行錯誤しやすい開発言語が求められるでしょう。また、今まで組み込み開発に関係なかったコンテンツ系開発者のアイデア実現が当たり前になるでしょうし、ネットワークとは縁のなかった組み込み開発者、製品開発者にそのスキルが必要とされるようにもなるでしょう。
その要求に答えるのにC言語では習得の容易さ、スピーディーな開発、試行錯誤のしやすさなどにおいて荷が重いと感じませんか?
mrubyはこのようなC言語のもつ問題を解決し、Rubyの持つ「書きやすく、習得しやすい」という特長を生かすことで、組み込み開発の抱える短納期、高機能、低予算、技術者不足といった課題の解決するものです。
mrubyは経済産業省のサポートを得て「平成22年度 地域イノベーション創出研究開発事業」「軽量Rubyを用いた組込みプラットフォームの研究・開発」において2年の歳月をかけて開発されました。
Rubyそのものは1995年にまつもとゆきひろ氏が発表したオブジェクト指向言語です。まつもと氏はMatz(マツ)という愛称で世界中で親しまれています。同様にRubyも世界で最も人気のあるプログラミング言語トップ10に選ばれるほど人気の高い言語です。
Rubyの特長は書きやすく読みやすく、習得しやすいところにあります。書きやすい、すなわちコード量が少ないため、生産性が高く(開発工数はJavaの1/5、コード数は1/2と言われていています)、さらにバグなどの不具合の軽減も期待できます。
筆者もmrubyの開発に参加していました。開発に当たってはMatzには相当無理をお願いし(いついつまでにこれが出来ていないと間に合いません!など)、その中で完成したmrubyは、提案時の16MBまで省リソース化の予定を大きく上回り、最終的には400KBでの動作を可能にしました。現在ではRAM100KBで動作、30KBを切る超省リソース化も実現しています。ちなみに「軽量Ruby」は開発コード名、言語としては「mruby」が正式名です。
実際に高生産性の例をご覧ください。下は文字列をTCP/IPでサーバに送信する例です。C言語とmrubyで比較しています。
- #include <stdio.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <string.h>
- int main(void)
- {
- int sock;
- int i;
- struct sockaddr_in svaddr;
- const char msg[] = "Hello!!";
- if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
- puts("socket() failed.");
- return 1;
- }
- memset(&svaddr, 0, sizeof(svaddr));
- svaddr.sin_family = AF_INET;
- svaddr.sin_addr.s_addr = inet_addr("192.168.1.1");
- svaddr.sin_port = htons(30000);
- if (connect(sock, (struct sockaddr*)&svaddr,
- sizeof(svaddr)) < 0) {
- puts("connect() failed.");
- exit(2);
- }
- for (i=0; i<10; i++) {
- if (send(sock, msg, strlen(msg), 0) !=
- strlen(msg)) {
- puts("send() failed.");
- exit(3);
- }
- }
- close(sock);
- return 0;
- }
- begin
- sock = TCPSocket.open("192.168.1.1", 30000)
- 10.times {
- sock.write("Hello!!")
- }
- sock.close
- rescue => e
- p e
- end
一見して分かる通り、mrubyのほうが遙かに簡単に書けることがご理解頂けるかと思います。
この例ではTCP/IPで通信するためにTCPSocketというクラスを使用しています。RubyでTCPSocketを使用するためにはrequire 'socket' を呼び出す必要がありますが、mrubyでは事前にライブラリを追加することでrequireなしで使用することができます。またrescueはRubyと同様に例外処理であり、簡潔に記述できます。
Copyright © ITmedia, Inc. All Rights Reserved.