Programming」カテゴリーアーカイブ

GNOME 3.26 gjs

GNOME 3.26 の目玉、gjs が ES6 フル対応になった。
これでで class が使えるぞ、Lang.Class の奇妙なコードとはおさらばじゃ。
んと、その前に。

#!/usr/bin/gjs

// 'gjs a.js 苗ちゃん'

const GLib = imports.gi.GLib;

for (let val of ARGV) {
    print(val);
    //let s = decodeURIComponent(escape(val));
    //print(s);
}

変わっていないや、まあいいか。
ClutterImage のセットが激遅なのもそのまんまだね。
ClutterImage PyGObject/Gjs | PaePoi

それはそれとして新機能だ。
GtkWindow を作ってみよう、やっぱり GUI だよね。

#!/usr/bin/gjs

imports.gi.versions.Gtk = "3.0";

const Gtk = imports.gi.Gtk;

class Test extends Gtk.Window {
    constructor() {
        super();
        this.connect("hide", ()=> {
            Gtk.main_quit();
        });
        this.show_all();
    }
}

Gtk.init(null);
let test = new Test();
Gtk.main();

これでウインドウを作るだけの最小限コードのようだ。

imports は PyGObject と同様にバージョン指定が無いと警告が出るようになった。
アロー関数を使えば Lang.bind を使わずにあの this の糞仕様を回避できる。
他の説明はいらないよね。

次はコード分割してみよう。

#!/usr/bin/gjs

imports.gi.versions.Gtk = "3.0";
imports.searchPath.unshift('.');

const Gtk = imports.gi.Gtk;
const Btn = imports.btn;

class Test extends Gtk.Window {
    constructor() {
        super();
        this.connect("hide", ()=> {
            Gtk.main_quit();
        });
        this.btn = new Btn.Btn("睦ちゃん");
        this.add(this.btn);
        this.show_all();
    }
}

Gtk.init(null);
let test = new Test();
Gtk.main();

var Gtk = imports.gi.Gtk;

class Btn extends Gtk.Button {
    constructor(lb) {
        super({
            label: lb
        });
    }
}

えーーーーー
let も const も定義していないお!
Java と違って同一ソースに複数の class が書けるのでこうすればいいけど。

#!/usr/bin/gjs

imports.gi.versions.Gtk = "3.0";

const Gtk = imports.gi.Gtk;

class Test extends Gtk.Window {
    constructor() {
        super();
        this.connect("hide", ()=> {
            Gtk.main_quit();
        });
        this.btn = new Btn("睦ちゃん");
        this.add(this.btn);
        this.show_all();
    }
}

class Btn extends Gtk.Button {
    constructor(lb) {
        super({
            label: lb
        });
    }
}

Gtk.init(null);
let test = new Test();
Gtk.main();

コードが長くなると…

モジュールとして継承 class は作ってはいけないってことかな?
まだ試したばかりだし他の方法はあるかもしれないけど。
なんか一気にテンションが下がった、PyGObject に戻るかなぁ。。。

GTK+ Cancel Long Keypress

GTK+ にてキーの長押しを判別する手段を発見。
GTK+ はキーの長押しを認識できないようで | PaePoi
こんなことを書いて 8 年もたってしまった、遅すぎるぞ俺!

何かキーを長押しした状態で event.time の値を見ると同一だった。
つまり長押しは最初に押した時間のまま延々とイベントが飛んでくるようだ。
とっととサンプルコードを書いたほうが解りやすいということで。

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class CancelLongKeypressWindow(Gtk.Window):
    """
        Wayland Only
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        self.connect("hide", Gtk.main_quit)
        self.connect("key-press-event", self.on_key_press_event)
        self.long_keypress = 0
        self.show()

    def on_key_press_event(self, widget, event):
        #
        # Cancel Long Keypress
        #
        if self.long_keypress == event.time:
            return False
        self.long_keypress = event.time
        #
        print("Press!")
        return False

CancelLongKeypressWindow()
Gtk.main()

これでうっかり長押ししてしまっても早送りみたいな状態を避けられる。
逆に長押しされているのを判別するということも可能、こんなに簡単だった。
Comipoli で使うのと 8 年前の記事に合わせるため Python にしました。
これで我が Comipoli で早送りされてしまうのを防げるぞと。

そういえばあの頃は Ubuntu を使っていたなぁ。
今度から GNOME に戻るんだっけ、良さげなら又使うかな?
って GNOME に Dock を付けるという余計なことを又してる、ヤメた。
筆者は MacBook Air でも Dock はまったく使わないんですけど。
第493回 Ubuntu 17.10の変更点:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社

追記
Wayland 環境だけのようです。
X.org でログインしたら同様にならなかった。

surrogate-pair

JavaScript における文字コードと「文字数」の数え方 | blog.jxck.io

そうだった、Python3 ばかり使っていたのでサロゲートペアのことを忘れていた。
GLib が扱う Unicode も Linux,macOS 版 Python3 の文字列も UCS-4 なんだよね。
Windows は捨てたので Windows 版 Python3 は知らん、ってどうでもいいか。

ES6 では for of を使って Python3 と同様な処理ができるようだ。
もちろん Node.js, JavaScriptCore も同様の結果でした。

UTF-16 はこの件があるし UTF-8 との変換も面倒だしetc…
何故いまだに Unicode の主流なんだろうね。
メモリ効率うんぬんならスクリプト言語や仮想マシンの時点で、って話だし。

おっと、一番下を見逃す所だった。

Family: Man, Woman, Girl, Boy Emoji

Emoji にはこんな文字をくっつけた一文字があったのか!
コピペしたら WordPress で投稿できないぞ、つかイッパイあるなぁ。

Emoji Version 2.0 List

Python3 でも駄目だ、バイナリを見れば当然だけど。
こんな文字まで考慮しなきゃいけない時代になってしまったのか。

JavaScript Arrow Function

前回 Gjs の ES6 がって書いたけど。
よく考えたら現在 JavaScriptCore や V8 も試せる環境じゃないか。
現状 (2017.10.10) ではどうなのか実験。

Gjs(SpiderMonkey) は 1.48.7
Node.js(V8) は dnf で入る v6.11.3
JavaScriptCore はワカラン、Fedora 26 の /usr/libexec/webkit2gtk-4.0/jsc
jjs(nashorn) は1.8.0_144、–language=es6 オプションで。

jsc は .bashrc にエイリアスを作って準備してと。
Node.js だけ console.log なのを無理矢理 print となるようにしてと。

とりあえず無名関数とアロー関数での this スコープの違い。

// @ Node.js
if (typeof print === "undefined")
    print = console.log; 

let obj = {
    func: function () {
        this.str = "優木苗";
 
        let funcA = function () {
            print(this.str);
        };
        let funcB = () => {
            print(this.str);
        };
        funcA();
        funcB();
    }
};
obj.func();

jjs はアロー関数に対応していなかった。
他は全部対応済なのね、ふむふむ。
Gjs はワーニングを出してくれる親切仕様、イラネーけど。

次は同一ブロックでの let 変数名の多重定義。

// @ Node.js
if (typeof print === "undefined")
    print = console.log; 

let n = 13;
let n = 99;
//n = 66;
print(n);

って、おい SpiderMonkey!
jjs ですらエラー判定するのに、まあ次は対応済と解っているけど。
それにしても Node.js のエラー表示はウゼェ。

次に class を作ってみよう、Gjs はまだ対応していないと解っているけど。

// @ Node.js
if (typeof print === "undefined")
    print = console.log; 

class Test {
    constructor(str) {
        print(str);
    }
}
let test = new Test("むったん");

だよね。
JavaScript の仕様策定は Mozilla がやっているはずなのにな。

GNOME 3.26 Gjs

GNOME 3.26 からの Gjs でついに class が使えるようになるようだ。
Lang.Class, Lang.Bind のあのもどかしさからやっと解放される。

Modern Javascript in GNOME // Speaker Deck

ただ this を親のままにするには無名関数でなくアロー関数を使う必要がある。
スライドを見ていてアレ?と思ったので調べただけですがwww
アロー関数は単なる省略表記だと勘違いしていた。

ES2015(ES6)新構文:アロー関数(Arrow function)|もっこりJavaScript|ANALOGIC(アナロジック)

async/await なんて非同期処理があると今頃知った。
node.js の非同期ってコレを使っているのかな?

async function – JavaScript | MDN

筆者は ES6 をまだまだ全然解っていないと思い知る。

テンプレートリテラル等は 3.24 から使えていたのでお馴染。
同一ブロックで同一名 let 宣言はエラー、って誰もやらないよ。
モジュールでは var にしないと public 宣言にならないってこと?
JavaScript の class は get/set が使えるのか。
ARGV が UNICODE にならないことについては何もふれていないな。
バイナリを直接扱う手段は、ってコレはバインドする側の仕事か。
今現在は試せないので詳しくは解らない。

ネタ切れで止まっているこのブログだけど来月は忙しいかも。
comipoli を作り替えしなきゃだし一部の Tips も書き換えだし。
って Fedora 27 が予定通りリリースされればって話だけーがさ。