Perl6 の正規表現は不思議なんじゃなくて、自由だった

ここ を見て Perl6 のコードに移植するっていうのをやっていた。
Perl6 の正規表現が不思議すぎるなーと思って書いていたんだけど、よく読んだら自由だったらしい。

function isNumber (x) {
    if ( typeof x === 'number' )      return true;
    if ( /^0x[0-9a-f]+$/i.test( x ) ) return true;
    return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test( x );
}

は Perl6 で書くと多分こうなる:

sub is-number($x) {
    return True if $x.WHAT ~~ Numeric;
    return True if $x      ~~ /^0x<[0..9a..fA..F]>+$/;

    $x ~~ /^<[-+]>?(<:digit>+)?(\.<:digit>*)?(e<[-+]>?<:digit>+)?$/;
}

ʕ•͡ω•ʔ 眠い

GMake サバイバルガイド 便利そうな関数編

make は前回の記事で十分使えるようになったんじゃないかと思います*1
私も険しいまけふぁいるの坂を駆け上がっている途中なので、ここで紹介できる関数は 2 つしかないのですが、
ええい、たらーん!!! という方もおられると思います。
そのような方はGNU make: Functionsをご覧ください。

notdir 関数

notdir 関数は実際 basename コマンドと一緒です。

# makefile
ref0 = ./packages/FParsec.1.0.2/lib/net40-client/FParsec.dll
ref1 = ./packages/FParsec.1.0.2/lib/net40-client/FParsecCS.dll

target-dir = ./bin/Debug

all:
    echo $(target-dir)/$(notdir $(ref0))

以上のファイルを makefileMakefile という名前でどこか空のディレクトリに保存し、make と打ってみてください。
以下のように表示されるはずです:

% make
echo ./bin/Debug/FParsec.dll
./bin/Debug/FParsec.dll

shell 関数

shell 関数はバッククォーテーション文字列で括ったコマンドっぽいことをするようなやつです。

shell 関数を知る前はこのように書いていましたが:

SDL2_INCLUDES  = `pkg-config --cflags-only-I sdl2`
SDL2_DEFINES   = `pkg-config --cflags-only-other sdl2`
SDL2_LIBS      = `pkg-config --libs sdl2)

SDL2GFX_LIBS   = `pkg-config --libs SDL2_gfx`

shell 関数を使うとこのように書けます:

SDL2_INCLUDES  = $(shell pkg-config --cflags-only-I sdl2)
SDL2_DEFINES   = $(shell pkg-config --cflags-only-other sdl2)
SDL2_LIBS      = $(shell pkg-config --libs sdl2)

SDL2GFX_LIBS   = $(shell pkg-config --libs SDL2_gfx)

バッククォーテーションで括ったところはコマンドは無くなって、例えば pkg-config --cflags-only-I sdl2 の結果が SDL2_INCLUDES にそのまま設定されます。 ビルドしてみると、このように出力されます:

% make -B
gcc -W -Wall -O2 -D_REENTRANT -I/usr/include/SDL2 -c main.c -o main.o
main.c: 関数 ‘main’ 内:
main.c:12:14: 警告: unused parameter ‘argc’ [-Wunused-parameter]
 int main(int argc, char ** argv) {
              ^~~~
main.c:12:28: 警告: unused parameter ‘argv’ [-Wunused-parameter]
 int main(int argc, char ** argv) {
                            ^~~~
gcc -lSDL2_gfx -lSDL2 -lSDL2 main.o -o demo-sdl2-gfx

実際にやってみたい方は ( ノ╹◡◡╹)ノ SDL2_gfx を使ったデモっぽいやつ をご覧ください。

参考

*1:多分、きっと、おそらく

GMake サバイバルガイド

この GMake サバイバルガイドでは、まけふぁいる*1をささっと書いて楽をしたいけど、
どーやって書くのかわからないといった様な人たちに向けてこんな感じに書けば良いんじゃないかなーというのを書いていると思います。

あと、この記事のまけふぁいるのサンプルコードは便宜上 4 半角スペースでインデントしていますが、まけふぁいるのインデントは絶対にタブなので、実際にやって見る場合は注意してください。

最新のソースコードを実行したい!

Crystal のソースコードコンパイルしてから実行するのは億劫ですよね。

% crystal build ./hoge.cr
% ./hoge
% crystal build ./hoge.cr
% ./hoge
% crystal build ./hoge.cr
% ./hoge
% crystal build ./hoge.cr
% ./hoge

何度も続けて行うなら、何とかして自動化してしまいたいもの。

まあ、cyrstal run ./hello.cr とかすれば Crystal のソースコードから実行できるんですが、それは無視します。

以下のようなへろーわーるどなソースコードがあったとします:

# hello.cr
puts "Hello, World!"

make ってやるだけで、実行ファイルがなかったり古かったりしたらコンパイルして とりあえず実行したい場合は私はまけふぁいるをこんな風に書きます:

.PHONY : run
run: hello
    ./hello

hello: hello.cr
    crystal build --release $^

.PHONY: run というのは run というシンボルはファイルじゃねーからよく覚えとけ!という意味を表明するために書いています。
これは省略可能です。

すぐ下の:

run: hello
    ./hello

こういうのをこの記事ではレシピ*2と呼びましょう。
レシピとはあるファイル○○を作るにはファイル△△が必要で、××するとできるというのをまけふぁいるの記述で書いたものです。
それをまけファイル用の記述で書くとこのようになります:

○○: △△
    ××

先程のレシピに戻ると run というファイルには hello というものが必要で、run を作るには ./hello が必要で、 hello コマンドを実行すればいいということが書いてあります。
しかし、run というファイルは実際には作成されないので、何度も実行することが可能です。

そういえば、hello はどうやって造られるのでしょう?
hello のレシピはすぐ下にあります:

hello: hello.cr
    crystal build --release $^

hello というファイルには hello.cr というファイルが必要で、crystal build --release $^ を実行すればいいよね!ということが書いてあります。
$^ は必要なファイル──この場合では hello.cr ですね──を参照する変数です。
作成するファイルを参照する変数は $@ なので、覚えておいてください。

とはいえ、この 2 つをもし忘れてもレシピは書けます。

hello: hello.cr
    crystal build --release hello.cr

という風に書けばいいだけだからです。
替わりにめんどくさいというだけです。

たくさんのソースコードの中で、新しいのだけコンパイルしたい!!

おーけーべいべ!
まさにそのために make は存在します。

例えば、ソースツリーに以下の LiveScript のソースコードがあったとします:

./routes.ls
./test/index.ls
./gulpfile.ls
./public/components/App.ls
./public/components/AddRoute.ls
./public/components/CounterRoute.ls
./public/store.ls
./public/action.ls
./server.ls
./config.ls

それに対して私の書いたまけふぁいるはこうです:

srcs = \
    gulpfile.js \
    routes.js \
    server.js \
    config.js \
    test/index.js \
    public/store.js \
    public/action.js \
    public/components/AddRoute.js \
    public/components/App.js \
    public/components/CounterRoute.js

.PHONY : build
build: $(srcs)

gulpfile.js: gulpfile.ls
    lsc --debug --no-header -b -c $^

routes.js: routes.ls
    lsc --debug --no-header -b -c $^

server.js: server.ls
    lsc --debug --no-header -b -c $^

config.js: config.ls
    lsc --debug --no-header -b -c $^

test/index.js: test/index.ls
    lsc --debug --no-header -b -c $^

public/store.js: public/store.ls
    lsc --debug --no-header -b -c $^

public/action.js: public/action.ls
    lsc --debug --no-header -b -c $^

public/components/AddRoute.js: public/components/AddRoute.ls
    lsc --debug --no-header -b -c $^

public/components/App.js: public/components/App.ls
    lsc --debug --no-header -b -c $^

public/components/CounterRoute.js: public/components/CounterRoute.ls
    lsc --debug --no-header -b -c $^

これでもまだ力技を使っていますが、わかりやすいかもしれませんね。

test/index.ls があるので、test はこのように書けるかもしれません:

test: test/index.ls
    mocha $^ --compilers ls:livescript

まけふぁいるでは、変数も使えます。

srcs = \
    gulpfile.js \
    routes.js \
    server.js \
    config.js \
    test/index.js \
    public/store.js \
    public/action.js \
    public/components/AddRoute.js \
    public/components/App.js \
    public/components/CounterRoute.js

が、その例です。
これは、○○や△△、××で使用できます*3
変数の値を参照するには $(src) のように、$() で変数名を囲みます。

変数を使わない場合、build はこのように、△△の部分が長くなってしまい、見るに絶えません。

build: gulpfile.js routes.js server.js config.js test/index.js public/store.js public/action.js public/components/AddRoute.js public/components/App.js public/components/CounterRoute.js

そういえば、build には××の部分が存在しないことに気づいていると思います。
build の××の部分は、既に△△のそれぞれの××が行っているので、必要ないのです。

(とはいえ、.o を使って実行ファイルや .dll.so を作成するような場合は必要です。)

今回は .ls.js にトランスパイルするだけなので、××は書いていません。

えーん、あるファイル一つだけ make したいよー

上の例で server.ls だけをビルドしたいとしましょう。
この場合は以下のように打つだけです:

% make server.js

public/components/CounterRoute.ls なら?

% make public/components/CounterRoute.js

ですね。

test/index.ls なら?

% make test/index.js

ですね。

make CounterRoute.jsmake App.js としないように気をつけてください。
それらは多分あなたが意図しているのとは違うファイルです。

そうそう、上の例で、make build と打つ必要はありません。
make と打つと、一番上のレシピ──この場合は build ──が実行されるからです。

いったんビルドしたのも全部ビルドしたいよ〜

make にオプション -B を付けてください。

% make -B

*1:Makefilemakefile ともいう。

*2:多分、ほんとは違う名前だと思う

*3:○○の部分には複数は指定できないかも?

LiveScript でつまずいたこと

関数呼び出し中の do

hoge-func ham, tomato, beacon do
  a: \foo
  b: \bar

が:

hogeFunc( ham, tomato, beacon, { a: 'foo', b: 'bar' } );

になって欲しいのだが、時々こういう風になる:

hogeFunc( ham, tomato, beacon({ a: 'foo', b: 'bar' }) );

うん、beacon はただの変数で、関数じゃねーよwwwwww
もうやだこの altJS…………。
地雷だよね………(´Д⊂グスン

これは、do を使う前の引数が変数だとなるらしい。

なので、今までやっていた通り:

hoge-func ham, tomato, beacon,
  a: \foo
  b: \bar

こんな風に書くことにする。

変数?方式の関数定義は上の方に変数がいっぱい溜まるし、普通に書きたいよー

こーいうのは:

apply-options = (options) !->
  heating-power            := options.power
  number-of-people-of-cook := options.number_of_people

こんな風に書ける:

!function apply-options (options)
  heating-power            := options.power
  number-of-people-of-cook := options.number_of_people

関数を渡す関数内で呼び出し元の this を使いたい

これは私のじゃっばすくりぷよぢからが 1200 万パワーに満たないために発生したことなんだけど:

class Cook
  (@skillet) ->
    
  cook: (foods) !->
    foods.for-each (food) !->
      # skillet は Cook インスタンスのものだが、このコンテキスト(for-each に渡された関数)においては
      # @skillet はないため、あぼーんする
      @skillet.push food

こういうことをやっていたために、実行すると激しくあぼーんしたり、挙動がおかしくなっていた。
LiveScript の公式サイトを目を皿のようにして眺めたところ、~> を使うと (・∀・)イイ!! らしいことがわかったので、このように変えた:

    
  cook: (foods) !->
    # 見づらいと思うけど、矢印(`->')の横棒(`-')をチルダ(`~')にすると(`~>')、
    # lsc がうまく計らってくれる。
    foods.for-each (food) !~>
      @skillet.push food
``

あんまり怖くないと思いたい null

多くの開発者にとって、null は忌避すべきものだ。
万が一、null に*さわってしまった*ら、あなたは突如発生した例外により、ヨルダン辺りまで吹き飛ばされるだろう。
あと、えーっと、オフィスの天井も失くなってしまう。
null の影響で行方不明になったり、命を失ってしまうえんじにゃーは毎年 500 万人を超える*1

このため、null をなんとかしようと様々な手法が開発されてきた*2

つーか、null を最初にだいにゅーさせなくすればいいんじゃね?

最初にどこかの変数に null をだいにゅーしておくと、長ーいコードの途中で長い時間をかけて膨らみ、いつしか破裂し、あなたを吹き飛ばす。

これはある。
っていうか、十中八九、これでぬるり*3がでてるんじゃないかと私の中では専らの話題である。

あと、クソ長いコードのせいで、どの時点でどの変数が null なんだっけ? とか考えるのすっごいめんどい。

Swift)なんかは言語仕様的にできなくしてるみたい。

あんまりないかもしれないけど、メソッドの最初の方に変数宣言をまとめるのやめようぜ?
変数宣言は必要な時に限ってその場で宣言しようぜ!!

( ◠‿◠ ) 変数宣言したけど、その時点ではだいにゅーするもん無いから null 入れとくわーwwwwww

とか、あかんやつだから!!!

null なんて無い方が良いよね………(過激派)

╰( ´◔ ω ◔ `)╯ まあ、無いなら無い方が嬉しいけどな

頭の良い null ならいいんじゃないかな

╰( ´◔ ω ◔ `)╯ わりぃ、あんまり思いつかなかったわ

public static NullExtensions {
    public bool IsNull<_Type>(this _Type self) where _Type : class {
        return self == null;
    }
}

ʕ•͡ω•ʔ Option か Maybe を返して、何か呼び出す時はその中で行うとか?

あとは……

int.Parse() じゃなくて、int.TryParse() 使おうなって五億回くらい言ってる。

*1:適当な数値であり、事実に基づいて書かれているわけではありません

*2:多分

*3:NullReferenceException のこと

ファイルのサイズを取得するには?

Strongtalk のソースコードを読んでいたところ、このような記述を見つけた:

void Bootstrap::openFile() {
    stream_ = fopen( file_name_, "rb" );
    if ( stream_ == NULL ) {
        has_error_ = true;
        lprintf( "\nCould not open file (%s) for reading!\n", file_name_ );
        exit( -1 );
    }

    int no = _fileno( stream_ );

    file_size_ = _filelength( no );
}

file_name_fopen 関数で開き、_fileno 関数で inode 番号*1を取得し、 それに対応するファイルサイズを _filelength 関数によって取得するのだが、うにっくす環境には _fileno_filelength が無いのである。

C言語でのファイルサイズ取得方法 を見ると、fseekSEEK_END を使うのは脆弱なので、 fstat を使えと書いてある。

ということで、書いてみた:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

inline off_t get_file_size(const char* filename) {
    struct stat file_status;

    stat( filename, &file_status );

    return file_status.st_size;
}

動かせるようにしたものがこっちに置いてある。

VC++ では stat眷属が 12 種類もあることは見なかったことにしておく。
窓に!窓に!

ちなみに githubStrongtalkコードでは該当箇所はコメントアウトされていた。

*1:と言って良いんだろうか?

カレー・ブルストの作り方

www.adventar.org

  1. ボイルしたソーセージ(ブルストとも呼ばれる。なるべく太いものが望ましい)を食べやすい大きさに切る。
  2. ケチャップを親の敵のようにかける。
  3. 死ぬほどカレー粉をまぶす。

╰( ´◔ ω ◔ `)╯ Windows でも Perl6 が使えるように rakudo を clone してビルドしてみたが、ビルドできなかった……

╰( ´◔ ω ◔ `)╯ その前にインストーラーを使ってインストールしておいたんだけどな

雨に唄えばおじさんと揚げ玉ビーチ

www.adventar.org

╰( ´◔ ω ◔ `)╯ またまた Swiff の話だ

╰( ´◔ ω ◔ `)╯ 多分な

換気扇の空、オリーブオイルの海、揚げ玉の海岸。
雨に唄えばおじさんは自分が厄介な場所に来てしまったことを悟った。

ということで、以下のコードはコンパイルエラーになる(はず):

let hoge : Nil  = nil;         // Nil のみの型を持つ変数の宣言はコンパイルエラーになる。

let piyo : int? = nil;         // Nil 許容型の変数に nil を初期値として設定するとコンパイルエラーになる。

let fuga : int  = nil;         // 整数型の変数に nil を初期値として設定するとコンパイルエラーになる。

hoge の方は、やっても意味がない宣言だと思う。nil しか設定できないし……。

piyo の方は、null 排斥運動におけるコンパイルエラー。
多くの場合、最初に null が入っているから NullReferenceException が送出されるので、 null を初期値として設定しないようにすれば多くの場合 NullReferencException を退けられるだろうという考えらしい。
Wikipedia では「安全性のために」としか書いてないけど。

fuga の場合はそりゃそーだよなって感じ。int 型の変数に nil は設定できない。

でも、こっちはどうだろう:

let hage = getHage();

getHage() がこうなっていると:

def getHage() : int? {
    if true {
        return nil;
    }
    42;
}

hage には nil が設定される。
こういう場合は、「nil しか返ってこなさそうですよ」って Warning を表示した方が良いんだろうか?
っていうか、こういう場合、Visual Studio*1 では到達不可能なコードなんちゃらあるって言われるよな………。

こういう場合は、やっぱりなんともならないよなぁ:

let hyoga = int.parse( "X" );

まあ、関数の戻り値の nil はいいことにしようっていうか、リテラルとしての nil を設定するのがダメってことなんだもんね。

あと、複合型の Nil 許容型とジェネリックな Null 許容型が 2 つあるとよくない気がしなくもない。

*1:っていうか csc とか