scala-modeの設定

ダウンロードと設置

Scala公式ページにEmacsの拡張がおいてある。
ダウンロードページの「Scala tool support」のファイルをダウンロードしてくる。

Scala Distribution | The Scala Programming Language

解凍すると「scala-emacs-mode」というディレクトリがあるので、
これを「scale-mode」という名前に変えて配置する。

$mv scala-emacs-mode ~/.emacs.d/packages/scala-mode

設定

「~/.emacs.d/config/10-scala-mode.el」というファイルを作成して以下のように書く。

(add-to-list 'load-path "~/.emacs.d/packages/scala-mode")
(require 'scala-mode-auto)

zencoding-modeの導入

以下のリンクから拡張ファイルをダウンロードして「.emacs.d/packages」に入れます。
http://emacswiki.org/emacs/ZenCoding


以下の内容を「.emacs.d/config/50-zencoding-mode.el」として保存します。

(require 'zencoding-mode)
(add-hook 'sgml-mode-hook 'zencoding-mode)

Plack::App::PHPCGIを読んだときに調べたこと

概要

Plack::App::PHPCGIは、PlackPHPを実行するモジュールです。
php-cgiを利用して実行しています。

Plack::Component

Plack::App::*」モジュールをつくるためのベースクラス。
prepare_appとcallをオーバーライドする。
callはto_appで呼び出されるようになっている。

Plack::App::PHPCGIでは以下のように実装している(コメント追加)。

sub prepare_app {
    my $self = shift;

    # PHPスクリプトのパス
    my $script = $self->script
        or croak "'script' is not set";
    $script = File::Spec->rel2abs($script);

    # php-cgiコマンドの設定、設定されていない場合はパスを自動検出する
    my $php_cgi = $self->php_cgi;
    $php_cgi ||= which('php-cgi');
    croak "cannot find 'php-cgi' command" unless -x $php_cgi;

    # _appはアクセサ。
    # wrap_php関数でPHPの設定
    $self->_app(wrap_php($php_cgi, $script));
}

sub call {
    my($self, $env) = @_;
    $self->_app->($env);
}

pipe関数

パイプを生成する関数。
forkした後に親プロセスと子プロセスで通信するパイプを作ったりすることができる。

use strict;
use warnings;

$| = 1;

pipe(my $rh, my $wh);

my $pid;
if ($pid = fork()) {
    # 親プロセス
    # 入力はしないため、閉じる
    close $rh;

    # 子プロセスにメッセージを送る
    syswrite($wh, '親メッセージ');
    close $wh;

    # 子プロセスの終了を待つ
    wait;
} elsif (defined $pid) {
    # 子プロセス
    # 出力はしないため、閉じる
    close $wh;

    # 親プロセスからのメッセージを受け取る
    sysread($rh, my $buff, 100);
    close $rh;
    print "親プロセスからのメッセージ: $buff\n";
} else {
    die "forkに失敗しました\n";
}

open関数

http://perldoc.jp/func/open

「>&」でリダイレクトができる。

use strict;
use warnings;

open my $fh, '>', 'test.txt';
open my $oldout, '>&', fileno($fh) or die "";

print $oldout "test";

warn fileno($fh);      # -> 3
warn fileno($oldout);  # -> 4

close $oldout;
close $fh;


「>&=」だとfilenoを再利用する。

use strict;
use warnings;

open my $fh, '>', 'test.txt';
open my $oldout, '>&', fileno($fh) or die "";

print $oldout "test";

warn fileno($fh);      # -> 3
warn fileno($oldout);  # -> 3

close $oldout;
close $fh;

## no critic

「## no critic」と書くことで、Test::Perl::Criticのチェックで無視されるようになる。
http://gihyo.jp/dev/feature/01/test-perl/0004


php-cgi

PHPをCGIで動かすためのプログラム。
このプログラムが標準入力(STDIN)でリクエストを受け取り、PHPプログラムで処理させて、標準出力(STDOUT)でレスポンスを返す。

wrap_php

以上のことを踏まえて、Plack::App::PHPCGIのwrap_phpメソッドを読む。

sub wrap_php {
    my ($php_cgi, $script) = @_;

    my $app = sub {
        my $env = shift;

        # 標準出力でphp-cgiとレスポンスをやりとりするためのパイプ
        pipe( my $stdoutr, my $stdoutw );

        # 標準入力でphp-cgiとリクエストをやりとりするためのパイプ
        pipe( my $stdinr, my $stdinw );

        # フォーク
        my $pid = fork();
        Carp::croak("fork failed: $!") unless defined $pid;

        # 子プロセス
        if ($pid == 0) { # child

            # シグナル
            local $SIG{__DIE__} = sub {
                print STDERR @_;
                exit(1);
            };

            # 子プロセスでは使わないので閉じる
            close $stdoutr;
            close $stdinw;

            # 環境変数の設定
            local %ENV = (%ENV, CGI::Emulate::PSGI->emulate_environment($env));
            local $ENV{REDIRECT_STATUS} = 1;
            local $ENV{SCRIPT_FILENAME} = $script;

            # 標準出力を$stdoutwにリダイレクト
            open( STDOUT, ">&=" . fileno($stdoutw) ) ## no critic
                or Carp::croak "Cannot dup STDOUT: $!";

            # 標準入力を$stdinrにリダイレクト
            open( STDIN, "<&=" . fileno($stdinr) ) ## no critic
                or Carp::croak "Cannot dup STDIN: $!";

            # php-cgiを実行
            exec($php_cgi,$script) or Carp::croak("cannot exec: $!");

            exit(2);
        }

        # 親プロセスでは使わないので閉じる
        close $stdoutw;
        close $stdinr;

        # psgi.inputの内容をphp-cgiに渡す
        syswrite($stdinw, do {
            local $/;
            my $fh = $env->{'psgi.input'};
            <$fh>;
        });
        # close STDIN so child will stop waiting
        close $stdinw;

        # cgi-phpからのレスポンスを受け取る
        my $res = '';
        while (waitpid($pid, WNOHANG) <= 0) {
            $res .= do { local $/; <$stdoutr> };
        }
        $res .= do { local $/; <$stdoutr> };

        # 子プロセスの終了が正常に終了した場合、レスポンスをPSGI形式にパースする
        if (POSIX::WIFEXITED($?)) {
            return CGI::Parse::PSGI::parse_cgi_output(\$res);
        } else {
            Carp::croak("Error at run_on_shell CGI: $!");
        }
    };
    $app;
}

yumとrpmについて

まとめようと思ったら、よくまとまったブログ記事を見つけた。

初心者の頃に知っておきたかった rpm と yum の違いと使い分け


デフォルトでtmuxがインストールできなかったので、以下を参照してレポジトリを追加した。
CentOS6でRPMforge、Remi、EPELをyumレポジトリに追加する方法

cpanfileとかMakefile.PLとかBUILD.PLとかcpanmとかcartonとか

自分の中でこんがらがってたのでまとめました。

cpanmとcartonの違いについて

どちらもモジュールをインストールするものです。

carton installの挙動は

cpanm --installdeps -L local/ . 

とだいたい同じ。

carton execの挙動は

perl -Mlib::core::only -Mlib=local/lib/perl5/

とだいたい同じ。

cartonはその上で提供していることは、
carton.lock というファイルにモジュールのバージョンとか記録しててくれて、いいかんじにバージョンを固定できる。


疑問点。
cpanfileというのが出てきて、cpanmでもモジュールのバージョンを固定できるようになった。
cartonを使ったほうが良い場合というのはどういう状況なのだろう?

Mojolicious::LiteでWebSocketを使ってボンバーマン

こちらのサンプルプログラムについて調べたことメモ。
mojomber


概要

f:id:memememomo:20130323190115p:plain

  • サーバに繋いだ分だけプレイヤーが作成されます
  • 矢印キーで移動、スペースで爆弾を置く
  • 爆発で自分が死ぬと自分のスコア(frag)が減ります
  • 爆発で相手が死ぬと自分のスコア(frag)が増えます
  • 爆発で死んだあと、5秒後に復活します

Websocketでやり取りする情報

  • ステージを描画する(drawarena)
  • プレイヤーを初期化(initplayers)
  • 爆弾を初期化(initbombs)
  • 新しいプレイヤー情報(new_player)
  • 他の死亡プレイヤーを削除する(old_player)
  • プレイヤー情報(player)
  • プレイヤーが生き返る(alive)
  • プレイヤーが死亡する(die)
  • スコア情報(frags)
  • 移動情報(move)
  • 爆弾情報(bomb)
  • 爆発情報(explode)

Javascriptモード追加

Javascriptモードにjs2-mode.elを使います。

https://code.google.com/p/js2-mode/


ダウンロードした「js2-mode.el」を「.emacs.d/packages」に置きます。
そして、以下のコマンドでバイトコンパイル。

$ emacs --batch -f batch-byte-compile .emacs.d/packages/js2-mode.el


設定は「10-js2-mode.el」という名前で「.emacs.d/config」において、以下のよう内容で設定。

(autoload 'js2-mode "js2-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.\\(js\\|json\\)$" . js2-mode))


autoloadってなんだろう、と思ってググってみたらバッチリな記事に遭遇。
起動時に必ず読み込む必要ない関数ならautoloadを使う

デーモンモードで使っている場合は、あんま意味ないのかな?