BenQさまからモニター用にScreenBar Halo 2をご提供いただきました。実は前作 ScreenBar Halo も頂いておりありがたい限りです。今回は前作との比較も含めてレビューします。
まず、設置はとてもかんたんで、ケーブルをつないで、モニターの上に乗せるだけです。前作でもかんたんでしたが、バネ部がよりソフトになったりいろいろと改良が加えられているようです。あと、接続ケーブルが独立したUSB-Cケーブルになったのは長さ調整の点からは嬉しいかな。
モニターランプとしては、前作よりもさらに広い範囲で手元が明るくなります。より手元が見やすくて嬉しいです。前作同様モニターへの映り込みもほとんどありません。より正確には、照らされて明るくなった手元が暗い画面だと少々映り込みますが、あまり気になりませんでした。
今回、もっとも改善された点はこのリモコンでしょう。前作のリモコンは乾電池駆動でしたが、今回は充電式になっています。前作で時々取れやすかった電池蓋問題がないのはいいですね。バッテリーはずいぶん長持ちするようで、しばらく使っていますが数週間程度ではなくならないようです。他に改善点として、現在の明るさレベル、色温度などがデジタル表示されるようになりました。もちろん、明るさも色温度もランプを見ればわかることではあるのですが、デジタル表示はガジェット感が向上していますね。もうちょっと暖かみがほしいとか、クールな方が良いとか自由自在です。
センサーがついていて、オートモードにすると部屋の明るさなどに応じて自動で明るさを調整してくれます。ただ、どうもオートにすると色温度は4000Kに固定みたいですね。惜しい。
あと、人感センサーもついていて、(設定すると)指定時間以上離席するとライトが勝手にオフになってくれます。席に戻ると自動でオン。いちいちリモコンを操作するのがめんどくさい人(私だ)には便利な機能です。前作はリモコン操作が面倒で使う頻度があまり高くなかった(リモコン操作を忘れてた)、この自動オン・オフはゲームチェンジャーです。
オートでの色温度が固定
箱に説明書が入っていなかった。ウェブでBenQサイトからPDFをダウンロードする必要があります。まあ、今風といえばその通りですが、説明書がないとわからない機能もあって、ダウンロードは必須です。せめてURLかQRコードで案内があれば試行錯誤なく、もうちょっと楽だったかも。
プリセットは 1 つだけ。お気に入りの設定ができるのはありがたいです。でも複数選べたらもっと良かったでしょう。
価格は高め。正直、同ジャンルでもっと安い製品はたくさんあります。が、確実に価値はあります。この価値をどう評価するかでしょう。自分で買っていないので偉そうには言えませんが。
最高級のモニターライトでした。前作よりも各所が改善されています。実用上の問題はほとんどありませんが、さらなる改善の余地は多少はありそうです。お財布に余裕がある方にはぜひ
購入はこちらから
※ あまりに久々すぎて画像の使い方とか忘れてます。せっかくのレビューなのに。
GitHubスポンサーの収入がありそうな気がしたので(注文時点では未取得)、デスクトップPCを購入することにした。
意外かもしれないが、初デスクトップ。今回はサイコムというところで注文した。自作という選択肢もあったが、自分の不器用さをよく承知しているので(最近では液漏れで止まった時計を修理しようと分解して、再起不能にした)、BTOに。スペックは、
で、先週届いて、早速Linux (Mint XFCE)をインストールしたのだが、しばらく使っていると突然落ちる。どうもグラフィック関係らしく、sshでログインして使っていると落ちない。GPUのベンチマークプログラムglmark2を実行すると即死。
で、購入先に相談したら、グラフィックボードの不良の可能性がありますね、と交換品を送ってくれた。慣れないなりにケースを開けて交換したら(思ったよりもずっと簡単だった。はまりそう)、問題は改善しなかった。ナンデ?
どうもハード不良ではなく、ドライバーに問題があるらしい。AMDからダウンロードしたドライバーも使ってみたのになあ。で、あきらめて近所のパソコン工房で購入した RX570 に交換。こっちはちゃんと動いた。私としては(若干損した気はするけど)ちゃんと動作するPCが入手できたので満足。
手元にはおそらく不良品ではない RX560 が2枚。これを購入先に送り返せばいいのかなあ。問い合わせ中。
サイコムから返事来た。送料着払いでボード2枚を返却したら、ボードぶんの代金を返金するとのこと。やさしい。
tDiary 5.1.0にアップデートした(前田修吾さんが)。あまり久しぶりなので、設定変更と確認しようとしたら、なにもかも忘れていて情けない。
Herokuに入社してもうすぐ8年になるのだが、ようやくアカウントを取得した。各方面で呆れられていた状態が解消した。
しかし、まだ使い方がよくわからないのであった。
いやあ、Ruby開発者の日記だというのにまだRuby 1.8で動作していて、恥ずかしい状態だったこの「Matzにっき」だが、前田修吾さんのご尽力で Heroku に移行しました。バージョンも 2.6.2 へ。
これで恥ずかしくない。最近は、主に Twitter か、Quora で書いてたけど、そろそろここも更新を再開するべきか。
久しぶりの更新
GitHubの<URL:http://github.com/matz/streem> を公開したら驚くべき反響の大きさなので、本人もびっくりしている。
ので、ここでちょっとまとめておく。
自分でもなにを言っているのかと思うけど、雑誌という出版物と比較して、超スピードとかでは説明のつかないネットとOSSコミュニティのバズり方を見た思いがする。
一方、雑誌連載のサンプルであるStreemだが、言語仕様についてはパッとした思いつき、というわけでもなくて、数カ月間、このような言語はあまりないし、実用的価値もありそうと思って作っている。
特徴
雑誌の連載のネタだとはいえ、今後も開発をやめるつもりもないので、ほそぼそと進歩し続ける予定。
っていうか、現在 C でタスクスケジューリングを実装することの困難さに絶望しつつあるので、マジで streeem を参考に Go で実装するかも。
Twitterで質問を受けたので、mrubyのmrb_gc_arena_save()/mrb_gc_arena_restore()の使い方という解説を行った。が、1つ140文字のTwitterでの解説にはどうしても無理があるので、こっちでまとめることにする。
まずは、Twitterの発言*1はこんな感じ。
arenaの目的。利用中のオブジェクトはGCに回収されないよう保護する必要がありますが、Cのスタックはポータブルに参照できません。そこでC関数実行中に生成したオブジェクトは全部「生きている」とみなす事で保守的に保護します。yukihiro_matz 2013-07-31 08:16:45
arenaの目的(2)。この保護のためにオブジェクトを記録しておく領域がarenaです。mrubyではデフォルトで100個のオブジェクトを登録できます。yukihiro_matz 2013-07-31 08:19:02
save/restoreの仕事。現状arenaのサイズは固定なのでC関数実行中にあまり沢山オブジェクトを生成するとarenaが溢れます。そこで沢山オブジェクトを生成する前後にsave/restoreを置くことでarenaのサイズを復元し、溢れを回避しますyukihiro_matz 2013-07-31 08:27:02
save/restoreの使い方。オブジェクトを生成する領域の前後をsave/restoreで囲みます。ただし、囲まれた範囲内のオブジェクトが保護されなくなりますから、どうしても必要なものはrestore後mrb_gc_protect()で改めて保護してください。yukihiro_matz 2013-07-31 08:33:61
これを再度まとめてみよう。
mrubyをCで拡張していると「arena overflow error」という「謎のエラー」に悩まされることがある。これはmrubyで「保守的GC」を実現している「GC arena」という領域があふれたというエラーだ。
GC(ガーベージコレクター)は、オブジェクトがまだ「生きている」、つまり、プログラムのどこかから参照されているかどうかを判定する必要がある。これはルートと呼ばれる参照から直接・間接に参照可能かどうかで判別する。ルートには、ローカル変数・グローバル変数・定数などが含まれる。
プログラムの実行がmruby VMの中でおさまっている時にはこれは問題ない。VMの持つルートはすべてGCからアクセス可能だからだ。
問題はCで記述された関数を実行中の時。Cの変数から参照されたオブジェクトも「生きている」わけだが、mrubyのGCはCの変数の内容を感知できないので、C変数からしか参照されていないオブジェクトは死んでいると誤解してしまう。
まだ生きているオブジェクトを回収してしまうのは、GCとしてもっともやってはいけないバグだ。
CRubyでは、Cのスタック領域を無理やりスキャンすることで、Cの変数をルートとしてチェックしている。もちろん、Cのスタックを単なるメモリ領域としてアクセスするわけだから、それが整数を意味する値なのか、ポインタ値を意味する値なのか判別することはできない。しかし、まあ、そこは「ポインタのように見える値は安全側に倒してポインタだと思って処理する」という方針で処理している。この「安全側に倒す」というポリシーのことを「保守的」と呼ぶ。
され、このようなCRubyの「保守的GC」にはいくつか問題がある。
その最大のものは「移植性のある方法でスタック領域にアクセスする方法がない」ということだ。つまり、移植性の高さを実現しようとするmrubyのような処理系では使えないってこと。
そこで、mrubyは別の方法で「保守的GC」を実現した。
問題なのは、C関数実行中に生成されたオブジェクトで、Rubyの世界から参照されてないオブジェクトのうち、C変数からは参照されているのでまだゴミ扱いしてはいけないものが存在する、ということだ。
既に述べたようにCRubyは、Cスタックをスキャンしてゴミのように見えるがゴミでないものを保護している。
しかし、その方法が使えないmrubyは、より保守的なポリシーを採用した。つまり、C関数実行中に生成されたオブジェクトは、極端に安全側に倒して、いっそ全部生きているとみなせば、少なくともゴミでないものを回収してしまう問題は回避できるんじゃないかと。
この結果、本当はゴミであるものを回収できないので、若干効率が下がることになるが、移植性が高いまま、保守的なGCを実現できることになる。CRubyで時々発生する「最適化で参照が削除されてゴミでないのにGCされた」問題とも無縁になる。
このポリシーで、「C関数実行中に生成されたオブジェクト」を登録しておくテーブルが「GC arena」である。arenaはスタック状になっていて、C関数の実行が終わるとその間に登録されたオブジェクトはポップされる。
原則としてはこれだけで、普通の場合は、これでめでたしめでたしなのだが、GC arenaの存在は別の問題を引き起こすことがある。これが前述した「arena overflow error」だ。
メモリが少ない環境でも動作することを考慮したmrubyはarenaのサイズを固定長にしており、しかも、そのサイズはデフォルトで100とかなり小さめに設定されている。
実は当初はサイズ1000とかちょっと大きめにしていたのだが、このテーブルサイズが厳しい環境があったのと、後述するようなテクニックを使い、適切にarenaを管理すれば100でも普通に動くので、現状は100にしている。
その結果、C関数の実行中に数多くのオブジェクトを生成すると、arenaがあふれることになる。
その対策に用いるのが、表題のmrb_gc_arena_save()とmrb_gc_arena_restore()というふたつの関数である。
int mrb_gc_arena_save(mrb)はGC arenaの現在のスタック位置を返し、void mrb_gc_arena_restore(mrb, idx)はarenaのスタック位置を保存された位置に戻す。
int arena_idx = mrb_gc_arena_save(mrb);...なんかオブジェクトを作る処理...mrb_gc_arena_restore(mrb, arena_idx);
というような使い方をする。
もともとのC関数の実行は、このようにsave/restoreに囲まれているのだが、一時的にオブジェクトを作り、その後は不要になる領域を明示的にsave/restoreを囲むことにより、arena overflowを避けるわけだ。
とはいうものの、具体例を見ないとわからないケースもあるだろう。ここでは、Array#inspectのソースを見てみよう。
static mrb_valueinspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list){ mrb_int i; mrb_value s, arystr; char head[] = { '[' }; char sep[] = { ',', ' ' }; char tail[] = { ']' }; /* check recursive */ for(i=0; i<RARRAY_LEN(list); i++) { if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) { return mrb_str_new(mrb, "[...]", 5); } } mrb_ary_push(mrb, list, ary); arystr = mrb_str_buf_new(mrb, 64); mrb_str_buf_cat(mrb, arystr, head, sizeof(head)); for(i=0; i<RARRAY_LEN(ary); i++) { int ai = mrb_gc_arena_save(mrb); if (i > 0) { mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep)); } if (mrb_array_p(RARRAY_PTR(ary)[i])) { s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list); } else { s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]); } mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s)); mrb_gc_arena_restore(mrb, ai); } mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail)); mrb_ary_pop(mrb, list); return arystr;}実際のコードをそのまま引用してきたので、若干複雑になっているが、Array#inspectの処理の本質は、配列の各要素をinspectメソッドを用いて文字列化した上で、それらを結合して配列全体のinspect表現を作ることにある。
全体のinspect表現の文字列を作ってしまえば、処理途中に生成した各要素の文字列はもはや不要になる。ということは、GC arenaにこれらのオブジェクトを登録しておく必要もない、ということだ。
そこで、ary_inspect()関数では、
という手順により、arena領域の消費を抑えている。
ここで注意すべき点は、最終結果となる配列inspect表現となる文字列は、mrb_gc_arena_save()の呼び出しよりも前に生成していることである。こうしないと、必要なオブジェクトがGCで回収されてしまうことになる。
処理のパターンとしては、さまざまな一時オブジェクトを生成した上で、そのうちの一部だけを参照し続けるというケースも考えられる。このようなケースでは、ary_inspect()のように既存のオブジェクトに結合するような手は使えないので、mrb_gc_arena_restore()の呼び出しの後にmrb_gc_protect(mrb, obj)を呼び出して、そのオブジェクトをarenaに再登録する必要がある。ただし、mrb_gc_protect()は注意して用いないと、これ自身がarena overflow errorの原因になることがあるので注意するように。
などということを、Twitterだけで説明するのは現実的じゃないよなあ。
あ、そうそう。
このmrubyのAPIには、改善が必要だなと思ってる点があって、その最大のものは、トップレベルでmrb_funcall()を呼ぶとGC arenaに戻り値が登録されるのでそのうちarena overflow errorになることだ。
戻り値を使わないmrb_funcall()のようなものを用意すればいいんだと思うんだけど。いい名前が思いつかないんだよなあ。
*1 tDiaryにTwitterの発言を引用するプラグインが欲しいなあ
先日、Webronza というところに寄稿したのだが、有料登録しないと後半が読めなくなっていた。で、交渉して公開許可を頂いたので、ここで全文掲載。
「ちょっと待った!小中学校でのプログラミング教育」
現代社会はもはやコンピュータがなければ成り立ちません。そして、コンピュータは誰かが作ってソフトウェアがなければ、まったく役に立ちません。コンピュータは自発的に仕事をしてくれないどころか、誰か人間がソフトウェアという形でどのように仕事をすれば良いのか教えてやらなければ、なんの働きもできないのです。コンピュータが社会に役に立っているのは、ソフトウェアがあるからです。
どんなに賢いように感じられるコンピュータでも、自らソフトウェアを開発することはできません。コンピュータは単純な計算をものすごく速く行うことができますし、それを積み重ねることで人間を越える能力を備えていますが、その一方で、なにか新しいことを創りだすなどの創造的な活動は苦手です。はっきりいうとまったくダメだと言ってもいいでしょう。当面の間は人間がソフトウェアを作って、コンピュータに仕事を教えてやるしかないのです。
社会におけるコンピュータの重要性は明らかで、そのコンピュータがソフトウェアがなければ役に立たず、そのソフトウェアは人間にしか作れないとなれば、ソフトウェアを開発する人間こそが真に重要だということになります。しかし、現状、誰でもがソフトウェアを開発することができない以上、ソフトウェアを開発する人、プログラマを養成することは急務です。とは言うものの、どのような教育を行えば、優秀なプログラマを育成できるのかについて誰でもが合意できる方法はまだ見つかっていないようです。
最近、注目されているのが若い人たち、特に小学生や中学生へのプログラミング教育です。確かに優秀なプログラマは若い頃からその才能を発揮している人が多いようです。また、プログラミング能力はあまり年齢に関係ないようで、天才と呼ばれる小学生プログラマがいると思えば、70歳をはるかに超えて現役で活躍する方もいらっしゃいます。
そこで、若いプログラマを育てるために、小学校や中学校での情報処理の教育やプログラミング教育に力を入れようという動きもあるようです。しかし、自分自身のプログラマとしての経験から考えると、これにはなかなか困難がつきまとうように思えます。第一の課題は「誰が教えるか」という点です。学校をプログラミング教育の現場にするためには、当然のことながらプログラミングを教える教師が必要です。しかし、現在の小学校・中学校の教員でプログラミングの能力を持つ人はごく少数でしょう。もちろん、教科書通りに教えることができる人は短期間で用意できるかもしれませんが、それでは子供たちにプログラミングに前向きな気持ちを伝えることは困難でしょう。中学生時代にプログラミングをはじめた私自身も含めて、若い頃からプログラミングに「はまった」人たちは、結局、コンピュータを使いこなすのが楽しいからこの道に進んだようなもので、教科書に書いてあるから、あるいは学校の授業だからという理由でプログラミングをはじめた人など見たことがありません。プログラミングを教えるというのであれば、少なくとも教える人はプログラミングの楽しさを自覚している人でなければ成果をあげられないと思いますし、そのような人をそれぞれの学校に配備するのは大変な困難ではないかと思います。
第二の課題は「どのように評価するか」ということです。学校の授業であるということは、なんらかの評価をする必要があるわけですが、これがまた困難です。まず、プログラミングの能力は、創造性をともなうという点である種芸術に似ています。そういう点では美術の授業に似ているのですが、問題はプログラミングの場合、人によっては非常に短期間で上達するため、小学生であってもプロを越える作品を完成させることがたびたびあることです。人によって出来栄えが10倍、100倍あるいは1000倍も違うようなものを学校の成績としてどのように評価したらよいのか途方にくれます。
第三の課題は「なにを教えるか」ですが、この点は最初のふたつの課題に比べればなきに等しいものです。
では、学校教育はプログラマ養成にふさわしくないのであれば、いったいどうすれば未来を担うプログラマを養成することができるでしょうか。
正しい答えは私自身も持っていないのですが、私の知っている優秀なプログラマのほとんどが自学自習でプログラミング能力を身につけている現実を考えると、あるいはプログラマとは、養成されるものではなく、発見されるものなのかもしれません。
ある調査によれば、大学におけるプログラミング教育の受講者の内6割程度はプログラミングの基本的な部分の理解に困難を感じ、それは他の学科の成績に必ずしも相関しなかったのだそうです。だとすると、世の中にはプログラミングに向いた性格の人がいて、成績その他では区別することができないことを意味します。であるならば、少しでもたくさんに人にプログラミングに触れる機会を与え、そしてそれに興味を持てた人、才能の片鱗を見せた人にはより豊かな機会を与えるようなプロジェクトを総合的に設計することで、未来のプログラマを「発掘」できるのかもしれません。そして、そのような才能あふれる人たちに適切な待遇を与えることが、このIT社会の競争力を強める最大の方策なのかもしれません。
一年ぶりの更新か。「年刊Matzにっき」だな。
今年もニューオーリンズで開催されたRubyConf。同じ都市で二度開催は初めて。
で、しょっぱなが私のキーノート。
まあ、あんまり語ることはないので。スライドを見てもらおうか。
こんな感じ。
角谷さんオススメのspeakerdeck.comも使ってみた。