Hatena::ブログ(Diary)

PBoMC

2011-09-28 小ネタ: ファイル名を一括変更

[] 小ネタ: ファイル名を一括変更

カレントディレクトリのファイル名を一括変更するためのシェルスクリプトを出力します。

これをファイルへセーブして、エディタ等で編集してから実行してください。

ファイル名の衝突はチェックしてませんのでご注意を。

#!/usr/bin/python3
#
# Prints a shell script for renaming files in current directory.
#
# Save the output to a file, edit and run it.
# Note: No check for name crashes!

import os

filenames = sorted(f if ' ' not in f else '"' + f + '"'
    for f in os.listdir('.'))
maxFilenameLen = max(len(f) for f in filenames)
for f in filenames:
    print('mv', f.ljust(maxFilenameLen), f)

# eof

2011-08-16 Re: お題:文字列を先頭から見て同じところまで除去

[] Re: お題:文字列を先頭から見て同じところまで除去

http://d.hatena.ne.jp/fumokmm/20110812/1313138407 をPureで書いてみた。

#!/usr/local/bin/pure -x

using system;

hoge [] = [];
hoge xs::list = hoge1 xs;

hoge1 xs = xs if any (== "") xs;
hoge1 xs = hoge1 $ map tail xs if have_common_leaders xs
    with have_common_leaders (x:xs) = all (\y -> x!0 == y!0) xs end;
hoge1 xs = xs otherwise;

do (puts.str.hoge) [
    ["abcdef", "abc123"],
    ["あいうえお", "あいうえさん", "あいどる"],
    ["12345", "67890", "12abc"],
    //
    [],
    ["abcdef"],
    ["abcdef", "abcdefghi", "abc"]
];

出力

% ./common.pure
["def","123"]
["うえお","うえさん","どる"]
["12345","67890","12abc"]
[]
[""]
["def","defghi",""]
%

2010-03-12 Pure

[] Pure言語を試してみた

最近、Pure (http://code.google.com/p/pure-lang/) という関数型言語に興味を持っている。

まず、二乗するsquareという関数を定義する:

> square x = x * x;
> square 3; square 5;
9
25
>

fooという変数を定義し、square foo を計算してみる:

> foo = 42;
> square foo;
1764
>

ここまではいたってフツーで、Haskell等と大して変わらない。さて、この時点では bar という変数は定義していない訳だが、ここで square (foo+bar) を計算しようとするとどうなるか? 大抵の言語では変数未定義エラーとなるだろう。Pureではこうなる:

> square (foo+bar);
(42+bar)*(42+bar)
>

ここに興味を惹かれた。よく知らないが、数式処理の方面ではこういう言語は昔からあるらしい (Mathematicaもこんな感じか?)。

コードの見た目はHaskellによく似ているものの、関数型言語には珍しい動的型、かつ正格評価であり、ラムダ計算ではなく wikipedia:項書き換え に基いたよりシンプルな言語なのだそうだ。前身のQ言語での反省から、より性能を重視し、バックエンドにはLLVMを採用している。

私は新たな言語を試す際には、Hello worldの次に基数変換のプログラムを書くことにしている。つまりこんな奴だ:

% ./base 42 0240 0xD000
42 == 0x2A == 052
160 == 0xA0 == 0240
53248 == 0xD000 == 0150000
%

ソースはこうなった。始めたばかりなので Pure らしい Pure プログラムにはなっていないと思う。

#!/usr/local/bin/pure -x

using system;

if compiling then ()
else puts $ join "\n" $ map toNumbers $ argv!!(1..argc)
  with toNumbers s = sprintf "%d == 0x%X == 0%o" (i, i, i)
    when i = case (chars s) of
      "0":"x":hex |
      "0":"X":hex = sscanf (string hex) "%x";
      "0":octal = sscanf (string octal) "%o";
      _ = sscanf s "%d";
      end;
    end;
  end;

型が動的である点や、未定義のシンボルがエラーにならない点などは、大規模開発向きではないような気もする。とはいえ、PerlPythonが (C++Javaと比較されつつも) けっきょく定着したように、これはこれで面白い使い道があるんじゃないか。もう少し使い込んでみようと思っている。

2009-12-10 Go言語とChromeブラウザでWeb Socketsを使ってみる

[][][] Go言語とChromeブラウザでWeb Socketsを使ってみる

GoとChromeがどちらも最近のリリースでWeb Socketsをサポートしたので、さっそく使ってみた。

まずはGoで書いたサーバ側。コンパイルして起動する。

package main

import (
        "bytes";
        "fmt";
        "http";
        "websocket";
)

const MAXREQSIZE = 0x10000;

func HelloServer(ws *websocket.Conn) {
        // fmt.Printf("received: %#v\n", ws);
        buf := make([]byte, MAXREQSIZE);
        ws.Read(buf);
        fmt.Printf("received: %s\n", buf[0:]);
        ws.Write(bytes.NewBufferString("Hello from server").Bytes());
}

func main() {
        http.Handle("/hello", websocket.Handler(HelloServer));
        err := http.ListenAndServe(":12345", nil);
        if err != nil {
                panic("ListenAndServe: ", err.String())
        }
}

次にクライアント側。ローカルファイルに保存する。

<html>
<head><title>Web Socket test</title></head>
<body>
<script>
var ws = new WebSocket("ws://127.0.0.1:12345/hello");
ws.onopen = function() {
        ws.send("Hello from client");
};
ws.onmessage = function(message) {
        alert("Message from server: " + message.data);
};
</script>
Web Socket test
</body>
</html>

サーバと同じマシンで動いているChromeでこのファイルを開くと、Chrome側ではアラート窓が出て "Hello from server" と表示され、サーバ側では標準出力に "Hello from client" と出ます。

2009-09-05 selective-display を単純化して使いやすく

[] selective-display を単純化して使いやすく

インデントの深さが現在行以上のものを隠す/隠さない、のトグル動作にしてみた。

(global-set-key [?\C-4]
 '(lambda ()
    (interactive)
    (if selective-display (set-selective-display nil)
      (back-to-indentation)
      (set-selective-display (current-column)))))

キーバインドはもちろんお好みで。私は、元の set-selective-display のキーバインドが Ctrl-x $ なので、ASCIIキーボードで$と同じキーにある4なら憶えやすいだろう、と思ってCtrl-4 に割り当てた。

追記 2009-09-07: しばらく試してみたが、「インデントが現在行より深いものを隠す」動作の方が使いやすいように思う。見たくない行にカーソルがある場面ってのがそもそも少ないわけだ。

(global-set-key [?\C-4]
 '(lambda ()
    (interactive)
    (if selective-display (set-selective-display nil)
      (back-to-indentation)
      (set-selective-display (+ (current-column) 1)))))