MessageBox.show @ Gjs and PyGObject

JavaScript の static メソッドはインスタンスからは呼び出しできない。

#!/usr/bin/gjs
 
class A {
    constructor(arg) {
        this.num = 'instance';
    }
    static static_method() {
        return 'staticmethod';
    }
}
A.num = 'static';
a = new A();
print(a.num); //=> instance
print(A.num); //=> static

print(A.static_method()); //=> staticmethod
print(a.static_method()); //=> ERROR!

当然である。
JavaScript の class は prototype の別表現でしかないから。

#!/usr/bin/gjs

function A() {}
A.func = function() {
    return 'staticmethod';
}
A.prototype.func = function() {
    return 'instancemethod';
}

print(A.func()); //=> staticmethod
let a = new A();
print(a.func()); //=> instancemethod

Python,C# 等の他言語ではインスタンスからでも呼び出しできる。

#!/usr/bin/env python3
 
class A:
    def __init__(self):
        self.num = 'instance'
    @staticmethod
    def static_method():
        return 'staticmethod'

A.num = 'static'
a = A()
print(a.num) #=> instance
print(A.num) #=> static

print(a.static_method()) #=> staticmethod
print(A.static_method()) #=> staticmethod

特に C# でよく見るけど、わざわざインスタンスを作ってからスタティックメソッドを使っている人の異様な多さを見ると JavaScript みたいなアクセスのほうがいいような。

そんなことより。
スタティックメソッドとインスタンスメソッドで同じ名前を指定してもいいんだ。
あまり自分のコードでスタティックを作らないから知らなかったよ。

ということで。
GtkMessageDialog で MessageBox.show を作ってみよう。
MessageBox.Show ではどちらの言語のコーディングスタイルにも合わないからね。
Gir の Gtk.Widget には show メソッドがあるけど無視できる。

#!/usr/bin/gjs

const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;

var MessageBox = GObject.registerClass({
    GTypeName: "MessageBox"
}, class MessageBox extends Gtk.MessageDialog {
    _init(text) {
        super._init({
            buttons: Gtk.ButtonsType.OK,
            text: text,
            secondary_text: "test"
        });
    }
    static show(text) {
        //let dlg = new MessageBox(text); @ error!
        let dlg = new this(text);
        dlg.run();
        dlg.destroy();
    }
});

Gtk.init(null);
MessageBox.show("Message");

new this(text) って変な感じ。

#!/usr/bin/env python3

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

class MessageBox (Gtk.MessageDialog):
    def __init__(self, text):
        Gtk.MessageDialog.__init__(
            self,
            buttons=Gtk.ButtonsType.OK,
            text=text,
            secondary_text="test" )
    @staticmethod
    def show(text):
        #dlg = self(text) @ error!
        dlg = MessageBox(text)
        dlg.run()
        dlg.destroy()

#Gtk.init(None) @ no need
MessageBox.show("Message")

PyGObject だとこう。

GUI を作っている時の print 代わりに。