タグ:programming ( 56 ) タグの人気記事
Emacs で C とか Perl とか Ruby のデバッグをすると気持ちいい
 全国のprintデバッグ愛好家の皆様、こんにちは。VSとかEclipseとかのIDE以外でデバッガを使ったことのない僕がやってきましたよ。

 最近、C言語でヒーコラ言ってる真っ最中な訳ですが、C言語だとprintデバッグがやりにくい訳で、デバッガ様の力を借りてみたくなった訳です。という訳で、巷で有名な gdb をちょっと試してみました。

 基本的な使い方は、以下を参考にしてます。
 で、なんだか Emacsからも使えるみたいなんで、試してみたんですが、これが使いやすくてびっくり。"M-x gdb" で起動すると、Emacs のソース上に、現在の行が黒三角で、ブレークポイントが赤丸で表示されます。後は、コマンドラインでの操作と同じように、s とか n でステップ実行できます。
a0057891_1245669.jpg


 あー、もしかして、Perl とか Ruby のデバッガもこんな感じで使えるのかなぁ、と思って調べてみたら、ビンゴ。それぞれ、以下の設定を .emacs に追加して、起動してやると(Perlの場合は "M-x perl-debug"、Rubyの場合は "M-x rubydb")、gdb と同じような感じでデバッグできます。
;; Perl デバッガの設定
(autoload 'perl-debug "perl-debug" nil t)
(autoload 'perl-debug-lint "perl-debug" nil t)

;; Ruby デバッガの設定
(autoload 'rubydb "rubydb3x"
"run rubydb on program file in buffer *gud-file*.
the directory containing file becomes the initial working directory
and source-file directory for your debugger." t)

 Emacsでの設定や、それぞれのデバッガの使い方については、以下を参照。

 これは・・・、今まで結構な時間を損していたかもしれない・・・。
[PR]
by fkmn | 2008-06-12 23:55 | IT
Emacs での JavaScript 開発は js2-mode で決まり!
 いままで、Emacs での JavaScript開発には javascript.el を使っていたんだけど、これがシンタックスハイライト(しかも、ショボイ・・・)ぐらいしか機能がなくて、全然満足してなかった。

 で、いい加減、良さげな elisp が無いかなー、とか思って探したら、js2-mode なんてものを見つけた。これ、スゴイ。

Stevey's Blog Rants: js2-mode: a new JavaScript mode for Emacs
js2-mode: Google Code

パッと目についた特徴をあげると、
  • シンタックスハイライトが正確
     javascript-mode では色がぐちゃぐちゃになるソース(例えば、prototype.js)でも、きれいに色をつけてくれる。再帰降下パーサを使ってるらしい。
  • JavaScript の不規則なインデントに対応している
     タブを押すごとに、インデントの位置が切り替わる。地味にうれしい。
  • 構文チェック機能がある

 なんでも、この js2-mode は、Emacs拡張を JavaScript で書けるようにするという、より大きなプロジェクトの一部なんだとか。壮大なプロジェクトだ。

 そんなわけで、JavaScript開発は js2-mode に乗り換え。ちなみに、設定はこんな感じ。タブ幅は 4 が好み(js2-mode のデフォルトは 2)なので、そう設定している。

(autoload 'js2-mode "js2" nil t)
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
(add-hook 'js2-mode-hook
'(lambda ()
(setq js2-basic-offset 4)))

[PR]
by fkmn | 2008-05-21 23:55 | IT
リゲス本(Rの基礎とプログラミング技法)読了
Rの基礎とプログラミング技法
Amazon.co.jp: Rの基礎とプログラミング技法

 他のプログラミング言語の素養はあるけれども、Rについては全くの初心者な僕にはちょうど良い本だった。Rという言語のだいたいの仕様や機能については分かった気がする。ただ、Rの基本にして奥義でもあるベクトル単位の処理については、まだちゃんとは身に付いてはいない。

 OOP の仕様については、ちょっと難ありかも。S3クラスだと機能的に不十分だし、S4クラスだと、機能云々の前に、まず字面が汚い。せっかくなんだから、JavaScriptライクな仕様にしても良かったのに。

 とは言いつつ、なかなか楽しい言語なのは確か。本を読み終わった後は、「どう書く.org」のお題を自分で解いてみたり、他の人(と言ってもRで解いてるのはほぼ一人だけなんだけどw)の解答を眺めたりしている。

 あと、ESS は便利なんだけど、バッファの評価に C-cM-b なんて微妙なキーバインドが割り当てられてるので、以下のような感じで C-cc に割り当て直した。あと、パラグラフを評価してから R のバッファに移動する関数を追加したり(キーバインドは C-cC-c)。


(add-hook 'ess-mode-hook
'(lambda ()
(defun ess-eval-function-or-paragraph-and-step-and-go (vis)
(interactive "P")
(ess-eval-function-or-paragraph-and-step vis)
(ess-switch-to-ESS t))
(local-set-key "\C-cc" 'ess-eval-buffer-and-go)
(local-set-key "\C-c\C-c" 'ess-eval-function-or-paragraph-and-step-and-go)

[PR]
by fkmn | 2008-05-12 23:55 | IT
Rはもっと評価されるべき(プログラミング言語的な意味で)
仕事で必要になりそうなので、R を少し勉強しだした。

準備としては、
  1. R.app をここからダウンロードして、インストール
  2. EmacsでのRプログラミングをサポートしてくれる ESS (Emacs Speaks Statistics) をインストール。使い方等は、RjpWiki の ESS のページあたりを参考に

で、少し触れてみた感想としては、結構な好感触。

 Scheme の影響を受けている、と言われているだけあって、リストはあるわ (*)、関数がファーストクラスオブジェクトだわ、遅延評価があるわで、内部的な動作が確かに Scheme っぽい。ところが、構文の見た目は括弧括弧してなくて、C言語っぽい感じ。そして、そんな C言語風の構文にも関わらず、代入 (アサイメント) の演算子が "=" ではなく "<-" だという所に、心をくすぐられてしまう。
* データ構造はリストだけじゃないけど

 これは、統計専門の言語にしておくのはもったいない。みんなもっと R をやるといいと思うよ。

 と、そんなわけで、Rの本を一冊買ってしまった。週末にでも読む予定。

Rの基礎とプログラミング技法
Amazon.co.jp: Rの基礎とプログラミング技法
[PR]
by fkmn | 2008-05-08 23:55 | IT
Ruby で、連続した数列を範囲形式にまとめてみる

問題
 並んだ数字を確認用にわかりやすくする為に、ソートされた数字の列をハイフンで繋ぐにはどうすればよいでしょうか?
(中略)

仕様

  • 数値は、半角スペースで区切られた文字列で渡されます。
  • 続いている部分は、最初の数値と最後の数値を-(ハイフン)で繋いだ表記にします。
  • 連続が1回の場合(前の数も後ろの数も連続でない)は、-(ハイフン)では繋ぎません。
  • 出力は、「,」(カンマ)と半角スペースで区切られた文字列でなければなりません。

Rubyでどう書く?:連続した数列を範囲形式にまとめたい - builder by ZDNet Japan

「Rubyでどう書く?:連続した数列を範囲形式にまとめたい」をやってみる - kenmazのはてな」経由


オイラならこう書くかなぁ(こっちの方がベターだ、という意味じゃないです)。

def nums2str_range(str)
nums = str.split(' ').map { |i| i.to_i }.uniq.sort
nums.inject([[nums.shift]]) { |r, s|
if r.last.last.succ == s
r.last << s
else
r << [s]
end
r
}.map { |i|
i.size > 1 ? [i.first, i.last].join('-') : i.first
}.join(', ') + '.'
end

str = '1 2 3 5 7 8'
puts nums2str_range(str) #=> 1-3, 5, 7-8.

str = '1 3 4 5 7'
puts nums2str_range(str) #=> 1, 3-5, 7.

一応解説。以下のような感じの事をやってます。
  1. 文字列を受け取って、半角スペースをデリミタにして配列へ変換(ついでに、重複を排除して、ソート)
  2. 数値が連続する部分ごとに配列を作成(以下のような感じ)
    [[1, 2, 3], [5], [7, 8]]
  3. 各配列ごとに、配列の長さが1より大きければ最初と最後の要素を取り出してハイフンで繋ぐ。



いじょ
[PR]
by fkmn | 2008-04-21 23:55
Perl で文字列中の変数名を明示的に指定する方法

文字列に式が埋め込めない。

Python の嫌いなところ - kwatchの日記

これはほかの言語も Ruby を参考にするべきだと思う。

Perl のは変数の直後に識別子に含めていい文字が来る場合にどうしていいかよくわからないのだよな。こんなん?
my $x = "a";
my $y = "$x\_b";

Pythonはダメなところは信者がアレすぎるところ - odz buffer


 変数の直後に識別子に指定できる文字が来てしまう場合は、展開して欲しい変数を ${変数名} という形で指定してやればおk。

 例えば、こんな感じ。
my $x  = "a";
my $xy = "b";
print "${x}y"; #=> ay

 でも、Ruby みたいに式を含めることはできないなぁ。


 Perl6 だと、ダブルクオート中の {} が Perl の式として展開されるらしい。

my $foo = 3;
my $hoge = "{$foo + 4}";
say $hoge; # 7

Pugs で Perl6 を体験する


[PR]
by fkmn | 2008-04-16 23:55 | IT
まずは遅延評価から、らしい
Y-combinator云々の前に、まず遅延評価らしい。
404 Blog Not Found:λ Calculus - まずは遅延評価から

ということで、弾さんのエントリを見ながらお勉強。


my $ELSE = 0;
sub {
my ( $a, $b, $c ) = @_;
return $a ? $b : $c;
}->( 1, 1, $ELSE = 1 + 1 );
print $ELSE; #=> 2

確かに、上のコードだと $ELSE が 2 になる。
(ただ書き写すだけじゃ面白くないので、元のコードを Perl で書き直した)。


var myif = function(_cond, _then, _else){
return _cond ? _then : _else;
};
こういう定義だと、一応

myif(true, 1, 1+1);
のようなものは動くけど、

function fact(n){
return myif(n <= 1, 1, n * fact(n-1));
};
のようなものは動かない。なぜなら、n * fact(n-1)は問答無用で実行されてしまうので、無限ループになってしまうからだ。

同じ話が SICPの問題1.6 にもあったなぁ。こういう動きのイメージは分かる。

先行評価する言語でも、クロージャーが使えるなら、それを利用して評価は後回しにできる。

なるほど、クロージャにしちゃえばいいのか。ということで、最後のコードも Perl で書き換え。

my $myif = sub {
my ( $_cond, $_then, $_else ) = @_;
return $_cond->() ? $_then->() : $_else->();
};

sub fact {
my $n = shift;
$myif->( sub { $n <= 1 },
sub { 1 },
sub { $n * fact( $n - 1 ) } );
}
print fact(10); #=> 3628800

ちゃんと動いた。

こうやって、順を追って説明されると理解できるなぁ。特に難しい話じゃない気がする。

となると、SICP の 問題1.6 も、new-if と sqrt-iter を書き直せばちゃんと動くはず。


(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))

(define (square x)
(* x x))

(define (improve guess x)
(average guess (/ x guess)))

(define (average x y)
(/ (+ x y) 2))

(define (new-if predicate then-clause else-clause)
(cond (predicate (then-clause))
(else (else-clause))))

(define (sqrt-iter guess x)
(new-if (good-enough? guess x)
(lambda () guess)
(lambda () (sqrt-iter (improve guess x) x))))

(define (sqrt x)
(sqrt-iter 1.0 x))

(sqrt 9) ;=> 3.00009155413138
(sqrt 100) ;=> 10.000000000139897
(sqrt (* 12 3)) ;=> 6.000000005333189

おぉ、動いた。わーい ヽ(´▽`)ノ
[PR]
by fkmn | 2008-02-05 23:55 | IT
Perl で Church数をいじってみた
Church数をちゃんと理解できているかいまいち不安だったので、Perl でちょっといじってみた。

まず、SICP の問題2.6の、zero と add-1(ついでに one)を Perl に移植。

my $zero = sub {
my $f = shift;
sub { my $x = shift; $x }
};

my $one = sub {
my $f = shift;
sub { my $x = shift; $f->($x) };
};

sub add_1 {
my $n = shift;
return sub {
my $f = shift;
return sub {
my $x = shift;
$f->( $n->($f) ($x) )
};
};
}

my $two = add_1($one);

# 数値に戻してみる
print $zero->( sub { $_[0] + 1 } ) (0); #=> 0
print $one->( sub { $_[0] + 1 } ) (0); #=> 1
print $two->( sub { $_[0] + 1 } ) (0); #=> 2


add_1 をもとに、任意の2つの数の加算ができるように変形。
$m->($f) で m の数をつくって、その回数分 $n->($f) ($x) を繰り返してやる。

sub add {
my ( $n, $m ) = @_;
return sub {
my $f = shift;
return sub {
my $x = shift;
$m->($f) ( $n->($f) ($x) );
};
};
}

my $three = add( $one, $two );
my $five = add( $two, $three);

# 数値へ
print $three->( sub { $_[0] + 1 } ) (0); #=> 3
print $five->( sub { $_[0] + 1 } ) (0); #=> 5


加算が出来ると、乗算も割と楽。
$m の回数分 $n->($f) を繰り返してやって、それを $x に適用させる。
# 上の add と比べて、変わってるのは * の部分だけ。

sub multi {
my ( $n, $m ) = @_;
return sub {
my $f = shift;
return sub {
my $x = shift;
$m->( $n->($f) ) ($x); # *
};
};
}

my $six = multi( $two, $three );

# 数値へ
print $six->( sub { $_[0] + 1 } ) (0); #=> 6


この調子で Y-combinator にまで進もうと思ったけど、Perl だと遅延評価が必要とか、Z-combinator とか言われて、正直よく分からんかった。。。

とりあえず、lambda だけで無限ループ(再帰)するのは簡単だよね、というところまで。

# 無限ループ(再帰)
my $omega = sub {
my $f = shift;
$f->($f);
};
$omega->($omega);



一応、Y-combinator がちゃんと理解できるまで続く予定。


参考サイト:
404 Blog Not Found:TuringとChurchの狭間で
The Mellow Musings of Dr. T : Recursive lambda expressions
[PR]
by fkmn | 2008-01-30 23:55 | IT
Perl の reduce (List::Util) で配列を作る方法
SICP の2.2.3節あたりを読んでいたら、思いついたのでメモ。

いままで reduce で配列を作る方法がいまいち分かってなかったんだけど、以下のようにすればいい。

例えば、1から3までの数字について、元の数字とその数字を2乗した数の対の配列を作る場合はこう。

my @array = 1 .. 3;
my $array_ref = reduce { [ @{$a}, [ $b, $b**2 ] ] }[], @array;
print YAML::Dump($array_ref);

実行結果

---
-
- 1
- 1
-
- 2
- 4
-
- 3
- 9

初期値に空の配列リファレンスを入れておいてやるのが(個人的な)ポイント。

Perl の(というより List::Util の)reduce は初期値を設定できなくて使いづらいと思ってたんだけど、ただ単に、配列の先頭に初期値を突っ込んでやればいいだけだった。コロンブスの卵。


参考サイト:
畳み込み関数の比較 (fold / accumulate / inject / reduce) - blanket sky
[PR]
by fkmn | 2008-01-24 23:55 | IT
livedoorクリップのタグをリネームする "Perl" スクリプト
livedoorクリップのタグをリネームするRubyスクリプト - むぅもぉ.jp
たぶんPerlで書いたらCPANのモジュール使えるかっらもっとシンプルに書けたのかな。

API, delicious compatible - livedoor クリップ まとめサイト - livedoor Wiki(ウィキ)
Net::Delicious を endpoint 変更のみでそのままご利用いただけます。


面白そうだったのと、Net::Delicious を使うと簡単に出来そうだったので、やってみました。

ldc_tag_rename.pl

use strict;
use warnings;
use Net::Delicious;

my $livedoor_id = "your_livedoor_id";
my $apikey = "your_api_key";

my $old_tag = shift or die "usage: $0 old_tag [new_tag]\n";
my $new_tag = shift;

my $ldc = Net::Delicious->new(
{ user => $livedoor_id,
pswd => $apikey,
endpoint => 'http://api.clip.livedoor.com/v1/',
debug => 0,
}
);

for my $post ( $ldc->posts( { tag => $old_tag } ) ) {
my $tags = $post->tags;
$tags =~ s/$old_tag/$new_tag/;

$ldc->add_post(
{ url => $post->url,
description => $post->description,
extended => $post->extended,
tags => $tags,
}
);
print $post->url, "\n";
sleep 1;
}


スクリプトの "your_livedoor_id" の部分に livedoor の ID、"your_api_key" の部分に API Key を入力してから使います。

実行する時は、コマンドライン引数に「変換前のタグ」と「変換後のタグ」を指定します。「変換後のタグ」を指定しないと、タグが削除されます。

# perl ldc_tag_rename.pl google Google


元エントリと同様に、実際に使う場合は自己責任でお願いします。自分で使ってみた限りでは、特に問題なく動作しましたが。


余談だけど、Net::Delicious に "$obj->rename_tag(\%args)" というメソッドがあって、一瞬期待したけど、livedoor クリップではまだ実装されていないらしかった。残念。


# 元エントリに trackback 打とうと思ったけど、URL が分からないなぁ。
[PR]
by fkmn | 2008-01-14 23:55 | IT


とあるWebアプリケーションエンジニアの日記
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
カテゴリ
以前の記事
ブログパーツ
リンク
検索
タグ
最新のトラックバック
プログラミングが「出来る..
from とりあえず9JP?
Genographic ..
from ナンジャモンジャ
ジュセリーノ
from ありの出来事
くちこみブログ集(ライフ..
from くちこみブログ集(ライフ)(..
以降、丁寧語で行こう!
from エッセイ的な何か
その他のジャンル
ファン
記事ランキング
ブログジャンル
画像一覧

fkmnの最近読んだ本 フィードメーター - フッ君の日常 あわせて読みたい AX