`getter` とか `setter` ってなんや?

なんなんでしょうね.


別に深い理解を目指すとかいうものではなく,ヒウィッヒヒーでちょうど getter について何か言ってたような言ってなかったような感じのツイートを見かけて (内容は忘れました),「よく見たらちょい不思議かも」ってのを思いついた日記になります.

オブジェクト指向

皆大好きオブジェクト指向.これに乗っかっていればイケイケプログラミングができるとされていたりいなかったりする.

こいつらを「見て」みて「自分がどう感じるか」について焦点を当てて考えてみた感じ.

プロパティについて

これは綺麗に読むことができる.大体どの言語でも,obj.property_name でアクセスができたりする.

len = a.length

これはそのまま

len is now a's length

のように読めて,まあ比較的自然に所有格か何かっぽい感じがする.

これはオブジェクトに限らず,構造体みたいなものでもこういう感じで書くものなので,オブジェクト指向より前から人々が自然であるとして作ったものなんだと思う.

メソッドについて

これが焦点.例えば次のような疑似コード片を書いてみる.

person p ("Tom");
std::cout << p.greet () << std::endl;
// output: Hi! I'm Tom!

これは恐らくよく見かけるオブジェクト指向っぽいとされるコードの例だと思う.オブジェクト指向は気持ち良く挨拶できる魔法のパラダイムであることが伺える.

このコードは見た感じでは p が主語になっていて,メソッドが動詞みたいなもんなんかなあって思える見た目をしている.

ところで,よく用いられるパターンとして,gettersetter なるものがある.らしい.雰囲気でコードを書いているのでよく知らない.

class SomeObject {
  private int a;
  public int getA() {
    return a;
  }
  public void setA(int newA) {
    a = newA;
  }
}

こんな感じのパターンってよく紹介されている.多分.

メソッドとして定義されているので単なる代入や読み出しだけじゃなくて色々モノを仕込めるみたいな.

これで安全性を確かめるみたいな話を仕込めばプロパティを安全に読み書きできるようになるみたいなことなんだと思う.とてもよいことですね.

さて,実際にこういう系のモノを使ったコードがどんな感じになるかっていうと,こんな具合.

const t = new TextArea();
t.setEditable(false);
t.show();
console.log(t.getPosition());

うん,なんかありそうなコードになった.

この場合,個人的によく考えたら謎っぽいのが t.setEditable(false); の主語って何ってところなんですね.

見た目から平叙文に直すと,こんな感じになる.

(A contextual subject) sets 'editable' of t as false
t shows itself
(A contextual subject) gets 'position' of t

オッ

さっきまでとは少し雰囲気が違って,明らかにメソッドなのに主語がそのオブジェクトっぽくないところがある.なんだよ文脈上の主語って.誰だお前.いやまあ 8 割くらい自分だけども.

なんか主語とかがすごいことになってるよね.

無理矢理 t を主語にするなら次のような感じになると思う.

t recieves false and sets it as its 'editable'
...
t let (us) know its 'position'

そうそうこんな感じ.

何か色々捻れてる気がする.

オブジェクト指向カプセル化うんたらの話からすると,この gettersetter もオブジェクトに隠された文脈 (まあ多分クラス定義とかの文脈) に存在する関数ってだけで,主語の話はどこにもないし,主語にするならオブジェクト自身であるというより「隠された文脈の中での主語」って具合であるところなんでしょう.

それでも結局コイツらはインターフェイスとして外に露出しているわけで,特に gettersetter は確実にその意図があって設計されているんすよね.見た目の主語がちんぷんかんぷんな印象を受けました.今までよく考えてなかったので昨日初めてそう思ったんですけど.

自分はこういうのは慣習に則るのが正解だと思っているので,特に反旗を翻すような実装例を提唱する気はないけど,よく考えてみると「おお,なんかちょっとだけ思ってたのと違うじゃん」ってなりますよね.なりました.

そもそものメソッド

メソッドって何?っていうのは辞書引くなり wikipedia 見るなりすればよく分かると思うので割愛します.ちなみに自分はよく分かってないです.

まあ書き方なんですけど,Ruby ではこう.

class ClassA
  # ...
  def method_a arg
    # ...
  end
end

b = ClassA.new
puts b.method_a 7

フツーっすね.とても良いことだと思います.これを見ても「ああ Ruby だ」ってなる感じですね.

Python だと多分こんな感じだった気がする.

# ...
def kick(self, target):
    # ...

ここで明示的に第一引数に self が出てきています.使うときは次みたいな.

a_friend_of_mine.kick(me)

定義したときには存在した self がカッコの中には存在しないですね.まあレシーバなんすけど.

他には,クラスが存在しない Go だとこんな感じでメソッドを書くはず.

(p *Person) greet(statement string) {
  fmt.Printf("I'm %s! %s!\n", p.Name, statement)
}

ここで明らかなように,メソッドを呼ばれるレシーバは第一引数,あるいは特別な引数として存在している感じ.

Lua にもクラスがなく,テーブルやら何やらの仕組みでメソッドっぽいものを書いたりするらしいですが,シンタックスシュガーとして次のような話があるらしい (書いたことはないですが).

# 下のふたつは大体同じ (厳密には評価の回数が違うとかなんとか)
a:move_to (pos)
a.move_to (a, pos)

まあ雰囲気は感じ取れますね.

C 言語でもそれっぽいものを書くことができて,次のようなものを見たことがある気がします (多分).

void window_move_to (WINDOW *w, int x, int y) {
  // ...
}

ここまで来ると「特別な第一引数がレシーバ」ってことがなんとなくわかる.クラス云々や構文的にレシーバであることを示す要素がなくてもそれっぽいです.

こういうのを見るとレシーバに対して,その情報を引き出して何かしたり,直接働きかけるものっていう感じがしてきました.あなたがそう思わなくても僕はそう感じています.

これを上手い具合に隠蔽してやるとあたかもオブジェクト自身が文脈を持って動いたり相互作用したりする世界になりそうっていう.

まあそうすると結局レシーバはメソッド定義時点では目的語で,外から見ると主語っぽい感じになってると嬉しいってとこなんすかね.

難しいことはよくわからないので賢い人に色々教えていただきたいです.よろしくお願いします.

総括

getter とか setter ってなんや?

xhyve で mikutter

xhyve 用の仮想マシンFreeBSD インストールして mikutter 使えるようにした日記 (結構前にやったから記憶があやふやかも) (というか酒飲みながら書いてるので余計あやふや)

環境

xhyve のインストール

% brew install xhyve

で多分おっけー

FreeBSD のインストール

適当なディレクトリを用意する (僕は $HOME/.xhyve/FreeBSD/ を作った)

% mkfile 16g storage.img

で 16GB の仮想マシン用ファイルを用意 (ddコマンド使ってもなんでもいいしサイズも適当でいい)

FreeBSD の公式サイトから最新の bootonly とかの iso をダウンロードしてくる

% uuidgen > uuid

とかして UUID を用意しておく

% mkdir boot
% ln -s /usr/local/share/xhyve/test/userboot.so boot/userboot.so

のようにして /usr/local/share/xhyve/test/userboot.so をとりあえず近くに持ってきた (あとで FreeBSD から userboot.so 持ってくるかもな〜的な)

#!/usr/bin/env bash

DIR=$(dirname $0)
ISO=$DIR/FreeBSD-11.2-RELEASE-amd64-bootonly.iso
STORAGE=$DIR/storage.img
USERBOOT=$DIR/boot/userboot.so
BOOTVOLUME=$ISO

UUID=$(cat "$DIR/uuid")

MEM=2G
SMP=2
PCI=0:0,hostbridge
NET=2:0,virtio-net
IMG=3:0,ahci-cd,$ISO
HDD=4:0,virtio-blk,$STORAGE
LPC=31:0,lpc
DEV=com1,stdio

KERNELENV=""

xhyve -A -U $UUID \
  -c $SMP \
  -m $MEM \
  -s $PCI \
  -s $NET \
  -s $IMG \
  -s $HDD \
  -s $LPC \
  -l $DEV \
  -f fbsd,$USERBOOT,$BOOTVOLUME,"$KERNELENV"

のようなスクリプト (僕は isoboot って名付けました) を用意して sudo で立ち上げ、いつものようにインストール

ifconfig で IP アドレスを控えておくのと sshd 有効にしておくことは一応やっておく (後で X11 Forwarding したいので)

UUID を固定しているので dhcp 云々でも IP アドレスは固定されるらしい (わからん)

インスコその他が終わったら

#!/usr/bin/env bash

usage() {
    cat << EOS >&2
Usage: $(basename $0) [-h,--help] [-s, --stdio]
  Up the VM.
Options:
  -s,--stdio    Run the VM, connecting console to STDIO.
  -h,--help     Show this message and exit.
EOS
    exit 1
}

DIR=$(dirname $0)
STORAGE=$DIR/storage.img
USERBOOT=$DIR/boot/userboot.so
BOOTVOLUME=$STORAGE

UUID=$(cat $DIR/uuid)

SMP=2
MEM=2048
PCI=0:0,hostbridge
NET=2:0,virtio-net
HDD=4:0,virtio-blk,$STORAGE
LPC=31:0,lpc
DEV=com1,stdio

KERNELENV=""

for opt in $@; do
    case $opt in
        '--stdio'|'-s')
            SIO=1
            ;;
        '--help'|'-h')
            usage
            ;;
    esac
done

if [[ -n $SIO ]] ; then
    xhyve -A -U $UUID \
          -c $SMP \
          -m $MEM \
          -s $PCI \
          -s $NET \
          -s $HDD \
          -s $LPC \
          -l $DEV \
          -f fbsd,$USERBOOT,$BOOTVOLUME,"$KERNELENV"
else
    xhyve -A -U $UUID \
          -c $SMP \
          -m $MEM \
          -s $PCI \
          -s $NET \
          -s $HDD \
          -f fbsd,$USERBOOT,$BOOTVOLUME,"$KERNELENV" > /dev/null 2>&1 &
fi

のようなスクリプト (これは up って名前にした) を用意して sudo ./up --stdio で標準入出力をどうたらで仮想マシンを立ち上げられるようになりました

この時点でのディレクトリの中身はこんな感じ

% tree -l
.
├── FreeBSD-11.2-RELEASE-amd64-bootonly.iso
├── boot
│   └── userboot.so -> /usr/local/share/xhyve/test/userboot.so
├── isoboot
├── storage.img
├── up
└── uuid

1 directory, 6 files

VM 内での準備

まず下準備として VM 内で

% sudo pkg install xauth git ruby devel/ruby-gems libidn

しておきます (xauthX11 Forwarding のために必要だったはず)

そして mikutter のインストール

% sudo gem install rake bundler
% git clone git://toshia.dip.jp/mikutter
% cd mikutter
% git checkout develop
% bundle install --path vendor/bundle

怒られたらググって解決します

完全に好みなんですがこの後 mikutterディレクトリを /opt/ に移しました

日本語環境

ここからは GUI 使うかもなので X11 Forwarding 云々でログインしてる前提です

% sudo pkg install ja-fcitx-mozc zh-fcitx-configtool
% sudo pkg install ja-font-migu ubuntu-font

fcitx-mozc とフォントを用意しておく (フォント云々はお好みで)

で 一回ログアウトしてもう一回ログイン

そしたら

% fcitx-config-gtk

して

fcitx を適当にこういう風にいい感じに設定しておく

f:id:d_flat_aug7:20181023033610p:plain

そして ~/.zshrc やらの *rc

#X11 forwarding: IM config

if [[ -z $FCITX_ENABLED ]] ; then
    if [[ -n $DISPLAY ]] && [[ -n $SSH_CLIENT ]] ; then
        export GTK_IM_MODULE=fcitx
        export QT_IM_MODULE=xim
        export XMODIFIERS=@im=fcitx

        mozc start > /dev/null 2>&1
        fcitx -r -d > /dev/null 2>&1

        export FCITX_ENABLED=1
    fi
fi

みたいなのを追記しておく

ついでに FreeBSD ではデフォルトで $HOME/bin にパスが通ってるので

#!/usr/local/bin/bash

LANG=ja_JP.UTF-8
LC_ALL=ja_JP.UTF-8
/opt/mikutter/mikutter.rb $@

こういうのを $HOME/bin/mikutter として用意しておく (僕はロケールen_US.UTF-8 にしてあるので)

終わったら再ログインなりなんなりして mikutter で起動するかどうか確認しておきます (ログイン時に fcitx 起動してなかったら fcitx -r -d しましょう)

その他

上で書いた up はデフォルトではバックグラウンド起動的な感じで ssh でログイン前提です

これから困るぞ〜ってときのために --stdio 用意してる的な (bash の簡単なオプション解析書く練習だったんだけど)

Gtk のテーマとかフォントとかの設定したいなら lxappearance とかインストールして設定するといいと思います (僕はさらに bzrbzr branch lp:ubuntu-themes して ubuntu のテーマ持ってきたりしてます) (ubuntu のテーマ綺麗じゃないですか?)

mikutter -d で mikutter は daemon で起動します

おわりに

さわやかておくれライフ!

桜ねねの頭髪になりたい

いや違うんですよ、決してオタクの「自分の嗜好に由来する性的欲求を煽るパーツ、あるいはそこに常に接触しているものになりたい」という部類のものではないんですよ。

もちろん、その文脈からの言葉でもあるのは確かで、あの綺麗で健康的な彼女のうなじには見惚れますし、その肩から見下ろす彼女の小さな体躯に見合わないほどのボディにはきっと大いに唆られるだろうと日々悶々としてはいますよ。

でもこの考えの本筋は全く違う思考の物語の先にあります。

やっぱり僕も日本人なので、この世の儚さ、あるいは厭わしさを憂う日々が続くこともあるんです。

そんなある日、たまたま気分で視聴するぞと決め込んでいたアニメを見ていると、僕の目の前にとある美少女が姿を現しました。言わずもがな桜ねねさんです。

彼女は明るく可愛く、それこそ天真爛漫で、言動や態度も言ってしまえば幼い部分もあります。しかし、ときには優秀さを発揮することもあったり、親友を思いやったりする優しさや自分の非を省みて落ち込んだりする人間らしさも見せてくれる、魅力的なキャラクターです。

初めは、そんな彼女にただただ魅了されるばかりでした。彼女が画面の中で慌ただしく表情を変えるのに合わせてニヤニヤとオタク笑いをしたり、彼女が出てくるシーンの中で気に入った箇所のスクショを保存したりなど、ジットリした鑑賞に耽る一般的な楽しみを満喫していました。

気がつくと、僕は彼女によって癒されていました。憂いの日々の中のオアシスです。

思い至った瞬間、「桜ねねになりたい」という衝動が僕を貫きました。これは間違いない、そんな確信を手に掴んだ感覚でした。

しかし、そこで僕は思い留まることができました。というのも、「僕のような陰鬱で矮小な存在が彼女になれるのか?」という後追いの疑心が沸々と湧き上がって来たのです。すぐに答えは出ました。決してなれないのです。仮にそのようになったとしても、それは彼女の姿をした僕であって、彼女のような輝きを放つ存在ではないのだろうという当然の結論でした。

そこでまた一つ前の感情に立ち戻ると、僕の本望は「桜ねねさんを見守り続けること」が正しかったのです。我々は「見ること」によって悩みを忘れ、精神の安寧を手に入れることで、初めて存在価値を取り戻す生き物です。

では彼女の周囲の人物として彼女を見守り続けるか。

違います。やはり彼女の周りにあるべき存在も僕では成りかわることができないものです。そもそも僕では、彼女の持つ交流の輪に参加していてはならないのです。

ここまで自省して、「せめて人間でなくてもいい、常に彼女と共にあるものを」と考えつくわけです。ですが、道具や衣類、装飾品などでは、場合によっては彼女に置いていかれることになります。とはいえ、利き手や脚など、体の一部となることを望むのも烏滸がましいのでした。

彼女の一部であって、彼女それ自身ではないものは何か。考え抜きました。

頭髪だ。

頭髪なら、あるいは最終的には抜け落ちたり、あるいは身だしなみの名の下に切られたりするものであり、究極まで彼女自身であるとはいえない、しかし彼女の一部として共にあり続けるものではないか。

この考え方ならば、もしかすると皮質や爪などでもいいかもしれません。少しこだわってしまったのは、前述のうなじ云々肩から見下ろす云々の邪念もあったからです。

このような経緯から、僕はこのタイトルのように思うようになりました。

人間として社会を生きることへの屈折した感情、そして少しの下心から、僕はこう言うんですよ。

桜ねねの頭髪になりたい