読者です 読者をやめる 読者になる 読者になる

言語間に寄るsplitの仕様の差異

たまたま、goで書かれた物をperlへ移植しようとしていたらsplitの挙動の差が出てきまして、他の言語の場合どうなるんだろうとぱっと思いついた言語で実行して見ました。以下の文字列を言語標準でついている文字列のsplitを実行した結果となります。

"/path/to/hoge/"
言語 結果
perl(5.12) ['','path','to','hoge']
golang(1.5) ["" "path" "to" "hoge" ""]
ruby(2.1) ["", "path", "to", "hoge"]
ptyhon(2.7.8) ['', 'path', 'to', 'hoge', '']
js [ '', 'path', 'to', 'hoge', '' ]
perl6 ("", "path", "to", "hoge", "") # (perl6-m -e 'say "/path/to/hoge/".split("/").perl')
clojure(1.4.0) ["" "path" "to" "hoge"]
php(5.5.14) [0] => [1] => path [2] => to [3] => hoge

単純にsplitをした結果、末尾の扱いに差異が見られました。


言語の樹形図を遡っていけばなんか分かるのですかね。


http://gigazine.net/news/20070126_computer_languages_history/

追記

結果の例の字がtypoしてました。これは、言語別に試したときにtypoしていたようです。

node-nopasteを作りました

npm installで手軽に入るnopasteが欲しかったので作ってみました。

  1. npm installでよほどnodeのバージョンが古くない限りは入るはずです。
  2. defaultの挙動がonmemoryなのでserverを落とすとそのままデータが消えます。
    1. nopaste本来の役割が一時的なデータの保存であるという意味合いがあるのでこうなっています。
    2. 永続化を希望する場合は、redisを立ち上げて環境変数からredisを指定してください。

www.npmjs.com

npm install node-nopaste

まだ0.0.1なので改善したいところなどありますが
ちまちまアップデートしていこうかと考えています。

hubot-karma-simple version up 0.1.4 and bug fix

先日npmにあげたhubot-karma-simpleですが再起動でデータが消える挙動が有りましたのでversion0.1.4にて修正いたしました。

www.npmjs.com

hubot-karma-simpleを作成しました

最近はbotを作るときはhubotというフレームワークを使用するのが一般的らしいです。例にも漏れず私の周りでもhubotを使用するようになりまして、独自実装されていたbotで泳いでいたkarma botもお役御免になったのですが新しく投入されたkarmaさんが従来型に対して色々欲しい機能が足りていなくて作ることに相成りました。(ただ、基本white list方式でこの手のbotを作成するのはどこに設置されるかわからないのである意味正しい判断だと思います)ちっちゃいコミュニティで、それなりにhubotいじれる人がいて育成していけるなら、対象をblack list方式で管理した方が楽しいと考えて作成しました。version0.1.0なのでまだ書き直したいところとか不足している機能等はありますが徐々に直していこうかと考えています。

npm,githubに登録してあります。


www.npmjs.com


github.com


インストール方法はnpmの方のページをご参照いただければおわかりいただけるかと思います。

特徴

  1. 発言内での複数の++,--へ対応しております
  2. 環境変数からコマンドの使用を制御することが可能です
  3. 環境変数からmessageとthingのblack listを制御する正規表現を投入することが可能です
  4. コマンドからalias,black_list,increment_message,decrement_messageを追加削除することが可能です

使用例

環境変数から各種コマンドを使用するかしないかの選択が可能です。

export HUBOT_KARUMA_SIMPLE_USE_COMMAND_INCREMENT_MESSAGE=1

各種コマンド

@hubot karma-simple increment_message 。゚ヽ(゚´Д`)ノ゚。
add increment_message 。゚ヽ(゚´Д`)ノ゚。

@hubot karma-simple alias @yourid yourid
add @yourid alias yourid

詳細はnpmjsの方を見ていただけるとおわかりいただけるかと思います。

参照

実装に当たり、hubotの全ソースコードcoffeescriptのリファレンス, karma,plusplus script等を参照させていただきました。

  1. https://hubot.github.com/
  2. https://github.com/github/hubot
  3. http://coffeescript.org/
  4. https://github.com/github/hubot-scripts
  5. https://github.com/ajacksified/hubot-plusplus

URI::QueryParamのquery_paramよりquery_param_appendを使用した方がいい理由について

URI::QueryParam - Additional query methods for URIs

https://metacpan.org/pod/URI::QueryParam

perlにはURI::QueryParamというモジュールがありまして、URIモジュールだけだと
届かない痒いところに手が届くことをしてくれるモジュールです。

例えば、uriから特定のパラメータだけを削りたいとかそういう場合
URIだけだと面倒なんですが、URI::QueryParamがあれば割と簡単に消せます。

# uri_query.pl
use strict;
use warnings;
use URI;
use URI::QueryParam;

my $uri = URI->new('http://google.com/');
$uri->query_form( a => 1 );
warn $uri->as_string;
$uri->query_param_delete('a');
warn $uri->as_string;
http://google.com/?a=1 at uri_query.pl line 8.
http://google.com/ at uri_query.pl line 10.

その逆の追加もよろしくやってくれて
同一パラメータでもちゃんと追加対象にしてくれています。

# uri_query.pl
use strict;
use warnings;
use URI;
use URI::QueryParam;

my $uri = URI->new('http://google.com/');
$uri->query_form( a => 1 );
warn $uri->as_string;
$uri->query_param_append( a => 1 );
warn $uri->as_string;
http://google.com/?a=1 at uri_query.pl line 8.
http://google.com/?a=1&a=1 at uri_query.pl line 10.

問題は初期化時にどうすべきか?
ということでして、通常であればこういう感じにしてあげれば
メソッドの利用目的にも合っているのではないかと思うのですが、

# uri_query.pl
use strict;
use warnings;
use URI;
use URI::QueryParam;

sub add_default_param {
   my $uri = URI->new(shift);
   $uri->query_param_append( a => 1 );
   $uri->query_param_append( b => 1 );
   $uri->as_string;
}

warn add_uri_param('http://google.com/?hoge=1');

条件

  1. 渡される引数が想定可能であり、
  2. なおかつ同一パラメーターが無い

query_paramとどちらをおすすめすべきか?を定量的に返したい。

  1. 想定できない場合においてはquery_param_appendが正しいはず。
  2. 一応運用上の問題点を挙げるなら、安易にまねされるケースがあり得るなどがあげられます。
  3. とりあえずそこを無視した場合にquery_param_appendを推奨するに足る根拠が欲しい。
use strict;
use warnings;
use Benchmark qw(:all);
use URI;
use URI::QueryParam;

my $count = 100000;

timethese($count, {
   query_param        => sub {
         my $uri = URI->new('http://google.com/');
         $uri->query_param( a => 1 );
         $uri->query_param( b => 1 );
         $uri->query_param( c => 1 );
         $uri->query_param( d => 1 );
         $uri->query_param( f => 1 );
         $uri->as_string;
   },
   query_param_append => sub {
      my $uri = URI->new('http://google.com/');
      $uri->query_param_append( a => 1 );
      $uri->query_param_append( b => 1 );
      $uri->query_param_append( c => 1 );
      $uri->query_param_append( d => 1 );
      $uri->query_param_append( f => 1 );
      $uri->as_string;
   },
});

とりあえず、2回ほど試してみた。

Benchmark: timing 100000 iterations of query_param, query_param_append...
query_param: 17 wallclock secs (17.43 usr +  0.00 sys = 17.43 CPU) @ 5737.23/s (n=100000)
query_param_append: 14 wallclock secs (13.20 usr +  0.00 sys = 13.20 CPU) @ 7575.76/s (n=100000)

Benchmark: timing 100000 iterations of query_param, query_param_append...
query_param: 19 wallclock secs (18.46 usr +  0.00 sys = 18.46 CPU) @ 5417.12/s (n=100000)
query_param_append: 14 wallclock secs (14.27 usr +  0.01 sys = 14.28 CPU) @ 7002.80/s (n=100000)

appendの方が高速のようだ。いったんこの結果が一つの理由になるので𠮷とする。
ただ、内部的にどうなのか追いたいので後日追記します。(短いのである程度は判明してますが)

coreutilsに何が入っているのか

いいコマンドがないか調べ物をしていると、それXXがあるよいわれ、更にそこからたどっていくとcoreutilsに入っていたというパターンにやたら遭遇するのでcoreutilsに何が入っているかを確認してみました。環境はUbuntuの14.04です。apt-get source coreutilsでソースがDLできたので
「ls man/*.x | wc -l」で104個ありました。確認してみたところ、普段よく見るコマンドは40個ぐらいでした。

cat - concatenate files and print on the standard output
chgrp - change group ownership
chmod - change file mode bits
chown - change file owner and group
cp - copy files and directories
cut - remove sections from each line of files
date - print or set the system date and time
du - estimate file space usage
echo - display a line of text
env - run a program in a modified environment
false - do nothing, unsuccessfully
head - output the first part of files
hostname - show or set the system's host name
groups - print the groups a user is in
kill - send a signal to a process
ln - make links between files
ls - list directory contents
mkdir - make directories
mv - move (rename) files
nice - run a program with modified scheduling priority
pwd - print name of current/working directory
rm - remove files or directories
sleep - delay for a specified amount of time
sort - sort lines of text files
stat - display file or file system status
tail - output the last part of files
tee - read from standard input and write to standard output and files
test - check file types and compare values
touch - change file timestamps
uniq - report or omit repeated lines
wc - print newline, word, and byte counts for each file
who - show who is logged on
yes - output a string repeatedly until killed
whoami - print effective userid
df - report file system disk space usage
dir - list directory contents


最初の頃、自分が知らなくてあとで知って驚いた名前から役割を勘違いしやすい物がわりとあります。例えば、普段ファイルを生成するためにtouchコマンドを使用したりするんですが、実はこのコマンド、「touch - change file timestamps」というコマンドでfileのタイムスタンプを更新するコマンドなんですよね。存在しないファイルを指定したときに生成してタイムスタンプを更新するから結果的にファイルを生成しているようです。オプションで -c をつけると生成しなくなるようです。killとかシステムコールでも同じ名前がついてるからそうなったんでしょうけどプロセスに対してシグナルを送信するためのコマンドでオプションで送信するシグナルが選べます。詳細についてはsignal(7)「Standard signals」で見られるようです。よく、kill -9 をしてプロセスを殺していますがSIGKILLしているだけだったりします。


残りの60個以上のコマンドはあんまり普段目にしないので、目についたものを実際に叩いてみます。

arch

マシンのアーキテクチャーを表示します。

x86_64
base64

引数で受けたファイルをbase64エンコードします。

  • dオプションでdecodeできます。
  1. http://ja.wikipedia.org/wiki/Base64
base64 TODO

IG11Y2ggdXNlIGZvciBpbWF4dG9zdHIgbm93YWRheXMsCiAgc2luY2UgdGhlIGludHR5cGVzIG1v
ZHVsZSBhbmQgbmV3ZXIgdmVyc2lvbnMgb2YgZ2V0dGV4dCBhbGxvdyB0aGluZ3MKICBsaWtlIF8o
InRydW5jYXRpbmcgJXMgYXQgJSIgUFJJZE1BWCAiIGJ5dGVzIikgdG8gd29yayBwb3J0YWJseS4K
ICBJIHN1c3BlY3QgdGhhdCAoaWYgc29tZW9uZSBjYXJlcyB0byB0YWtlIHRoZSB0aW1lKSB3ZSBj
YW4gcmVtb3ZlCiAgYWxsIGluc3RhbmNlcyBvZiBpbWF4dG9zdHIgYW5kIHVtYXh0b3N0ciBpbiBj
basename

/paht/to/filenameというような文字列をfilenameだけにします。

basename /path/to/filename
filename
chroot

ルートディレクトリを変更するコマンド。
Jailコマンドと一緒に使用する物らしい。

  1. http://linuxjm.sourceforge.jp/html/GNU_sh-utils/man1/chroot.1.html
  2. http://www.usupi.org/sysad/125.html
  3. http://www.asahi-net.or.jp/~aa4t-nngk/jail.html
comm

事前にsortされた2つのファイルを行ごとに比較する。
下記のような3カラムを出力する。

-1     suppress column 1 (lines unique to FILE1)
-2     suppress column 2 (lines unique to FILE2)
-3     suppress column 3 (lines that appear in both files)
csplit

与えたパターンに従ってファイルを分割します

csplit NEWS /\n/

0
169442

# 出力されるファイル
xx00
xx01

# パターンを適用する回数も指定できる
# 大量にファイルができるので注意が必要
csplit NEWS /\n/ '{*}'
  1. http://linuxjm.sourceforge.jp/html/GNU_textutils/man1/csplit.1.html
dd

ファイルを変換してコピーする。
convオプションを使用すると変換ができる

dd conv=lcase if=NEWS of=/tmp/NEWS

330+1 レコード入力
330+1 レコード出力
169442 バイト (169 kB) コピーされました、 0.00105946 秒、 160 MB/秒
dircolors

lsを使った際に表示される色の設定をするコマンド。
コマンド叩くと大量に設定が出てきます。

dircolors

LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:';
export LS_COLORS
dirname

ディレクトリ名だけをパスから取得する

dirname /path/to/name

/path/to
expand

タブをスペースに変換する

expr

単純に計算をしてくれます。

expr 1 + 60

61

expr 2 '*' 60

120
factor

素因数分解をしてくれるコマンドです。

factor 10

10: 2 5
fmt

テキストの幅やスペースを整形してくれるフォーマッタ。
使ってみたんだがいまいち期待した動作をしてない気がする。

fold

指定した長さやバイト数で行の折りたたみを行うコマンド。

fold -w 20 NEWS


Texts, and with no B
ack-Cover
Texts.  A copy of th
e license is include
d in the "GNU Free
Documentation Licens
e" file as part of t
his distribution.
install

指定されたファイルをコピーして属性を指定するコマンド。
cpと違って属性を指定できるのが特徴。

install -v ./src/install.c  /tmp/src
`./src/install.c' -> `/tmp/src/install.c'
join

2つのファイルの共通の行を統合して出す。

> cat > file1
1,2,3
4,5,6
7,8,9

> cat > file2
1,2,3
4,5,6
7,8,9
10,11,12

> join file1 file2
1,2,3
4,5,6
7,8,9
link

ファイルのリンクを作成する。

> link file1 linkfile

> ls -al
08:58 file1
08:59 file2
08:58 linkfile

# リンク元のファイルのタイムスタンプを更新
> touch file1
> ls -al
09:04 file1
08:59 file2
09:04 linkfile
mkfifo

名前付きパイプを作成する。
別の言い方をするとFIFOスペシャルファイル
UNIXにはpipeという機能があるのですがこれに名前をつけた物がそれです。
データを名前付きpipeに書き込んでそれをファイルとして扱うなどが用途として考えら選れる。

> mkfifo named_pipe
  1. man mkfifo
  2. man 3 mkfo
  3. http://uyota.asablo.jp/blog/2012/08/17/6544850
  4. http://ja.wikipedia.org/wiki/%E5%90%8D%E5%89%8D%E4%BB%98%E3%81%8D%E3%83%91%E3%82%A4%E3%83%97
mknod

スペシャルファイルを作成するコマンド
block,charctor,fifoといったスペシャルファイルを作成できる。

> sudo mknod sfile b 11 0

# less /proc/devices
  1. info mkcnd
mktemp

テンポラリファイルを作成する。

  • dで添付ディレクトリを作成する。
> mktemp
/tmp/tmp.dPp4YD0dMc
> mktemp -d
/tmp/tmp.IM0k9iEPqR
> file /tmp/tmp.IM0k9iEPqR
/tmp/tmp.IM0k9iEPqR: directory
nohup

ハングアップシグナルを無視してコマンドを実行してttyへ出力しない。
端的に言い換えると、ログアウトした場合もバックグランドでコマンドが実行される。

> nohup echo "hoge"
nohup: 入力を無視し、出力を `nohup.out' に追記します
> cat nohup.out
hoge


blog.glidenote.com

nproc

使用可能なプロセスユニット数を表示する。

> nproc
3
numfmt

数値を人間が読みやすいようにフォーマットする
manでマニュアル読むと--toに設定できる物が載っている。

> numfmt --to=si 1024
1.1K
od

ファイルを8進数もしくは他の形式で出力する。
主にバイナリファイルを16進数で表示したりする。

> od -x /bin/dir
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000020 0002 003e 0001 0000 4890 0040 0000 0000
0000040 0040 0000 0000 0000 a700 0001 0000 0000
0000060 0000 0000 0040 0038 0009 0040 001c 001b
paste

ファイルを行単位でmergeする。

> paste /tmp/file1 /tmp/file2
11111   33333
22222   44444
# /tmp/file1
# 11111
# 22222
# /tmp/file2
# 33333
# 44444
pathchk

ファイル名が有効か可搬性があるかどうかを調査する。

> pathchk /tmp/_x_dir
pinky

ログインしているユーザーの情報を表示

> pinky
ログイン 名前               端末   待機 開始時刻     ログイン元
hoge hoge             pts/0           2015-03-21 15:25 xxx-xxx-xxx-xx-xxx.xxx.xxx.ad.jp
pr

印刷用にテキストファイルをコンバートします。

> pr -W 20 README

under the terms of t
any later version pu
Invariant Sections,
printenv

環境変数を表示する。
envとの違いがよく分からない。

> printenv

EDITOR=/usr/bin/vim
GIT_EDITOR=vim
GOROOT=/usr/local/go
LANG=ja_JP.UTF-8
printf

Cなどでおなじみのデータをフォーマットしてくれるコマンド。

> printf "%05d\n" 100
00100
ptx

ファイルの内容の整列済み索引を出力する。

> ptx README

written ChangeLog entry,/           A complete patch includes a well-
in the "GNU Free/                   A copy of the license is included
/only partial (and incompatible)   ACL support, so although ".//
The solution is to turn off   ACL support manually via ".//
readlink

シンボリックリンクのリンクを解決して実態のファイルのパスを表示するやつ。

> readlink /lib/cpp

/etc/alternatives/cpp
rmdir

空のディレクトリを削除する
rm -rに近い気がする。

> rmdir hoge
runcon

指定されたセキュリティコンテキストでコマンドを実行する。
SELinuxの関連らしい。

seq

連続した値を出力します。

> seq 5
1
2
3
4
5
sha1sum

SHA1チェックサムを計算、チェックする。

> sha1sum README
8478daeff15e747906448f1471e09a62e59f457c  README

類似に以下の様な物がある。

sha224sum - compute and check SHA224 message digest
sha256sum - compute and check SHA256 message digest
sha384sum - compute and check SHA384 message digest
sha512sum - compute and check SHA512 message digest
shred

ファイルを上書きして、完全に消す。
rmの場合は(extundelete)復旧できる可能性がある。

> shred /tmp/tmp.OxrpPi3D3t
  1. https://tech.aucfan.com/rm-rf-retrieval/
  2. http://exlight.net/linux/extundelete/index.html
shuf

ランダムな順列を作成します。

> shuf /tmp/file1
11111
22222
> shuf /tmp/file1
22222
11111
split

ファイルを分割する
csplitのほうが若干便利そうなきがする。

> split -1 /tmp/file1
xaa
xbb
stdbuf

標準入出力ストリームのバッファ動作を変更して指定されたコマンドを実行します。
バッファリングの調整に使われるのを発見してびっくりした。

> stdbuf -o0 -e0 echo "hello" > /tmp/aaa
  1. http://linuxjm.sourceforge.jp/html/GNU_coreutils/man1/stdbuf.1.html
  2. http://sweng.web.fc2.com/ja/program/shellscript/stdbuf.html
stty

端末ラインの設定を変更表示する。

> stty
speed 38400 baud; line = 0;
eol = M-^?; eol2 = M-^?;
-brkint -imaxbel iutf8
sum

ファイルのチェックサムとブロック数を表示する。

> sum README
02047    11
sync

ファイルシステムが持っているバッファーをフラッシュします。
ちなみに昔は3回打つとか合ったようです。

> sync
  1. http://www.ne.jp/asahi/tao/elis/bitfaq/s004.html
  2. http://www.math.kobe-u.ac.jp/~kodama/tips-disk-cache-flush.html
tac

ファイルの行を逆順にして表示します。

> tac README | tail -n 3

the GNU fileutils, sh-utils, and textutils packages.
These are the GNU core utilities.  This package is the union of

> head -n 3 README
These are the GNU core utilities.  This package is the union of
the GNU fileutils, sh-utils, and textutils packages.
timeout

コマンドをタイムアウトをつけて実行します。

> time timeout 20 sleep 100
timeout 20 sleep 100  0.00s user 0.00s system 0% cpu 20.002 total
tr

文字を変換消去する。

> cat README | tr '[:lower:]' '[:upper:]'

INVARIANT SECTIONS, WITH NO FRONT-COVER TEXTS, AND WITH NO BACK-COVER
TEXTS.  A COPY OF THE LICENSE IS INCLUDED IN THE "GNU FREE
DOCUMENTATION LICENSE" FILE AS PART OF THIS DISTRIBUTION.
truncate

ファイルのサイズを指定されたサイズに切り詰めもしくは拡張する

> truncate -s 1000000 testfile

-rw-rw-r-- 1 hoge hoge 1000000  321 22:25 testfile
tty

標準入力に接続されている端末のファイル名を出す。

> tty
/dev/pts/7
uname

システムの情報を出力する。

> uname
Linux
unexpand

スペースをタブに変換します。

unlink

シンボリックリンクの削除に使います。
間違って実態を消すことが無いのでrmよりはこちらを使用した方がいいです。

> unlink slink_file
uptime

現在時刻やシステムが起動してからの時間やLAなどを表示します。

> uptime
 23:13:56 up 8 days,  5:07,  1 user,  load average: 0.00, 0.01, 0.05
users

現在ログインしているユーザーの一覧を返します。

vdir

ディレクトリ内部のコンテンツを表示します。
lsのオプションでも代用できそう。

vimでperlを開発するための最小限の設定

必要最小限でvimでのperl開発(utf8)するのにどんな設定渡したらいいかなと考えてまとめてみました。
多分これでいけそうな気がしてる。(要検証)これを作成した過程で不要な設定などいくつか自分の環境における不要な設定が発見できたのはよかった。

代表的な物は以下の2つかな。

  1. termencoding
  2. nocompatible see Vim - set nocompatibleはもういらない - Qiita

fileencodingとfencの関係がいまいちよく分からないので後で調べます。

.vimrc

"must
set expandtab
set shiftwidth=4
set shiftround
set autoindent

set fileencoding=utf-8
set fileencodings=utf-8
set encoding=utf-8 
set fenc=utf-8 

"optional
set number
set hidden
set hlsearch

augroup filetypedetect
autocmd! BufNewFile,BufRead *.t setf perl
autocmd! BufNewFile,BufRead *.psgi setf perl
autocmd! BufNewFile,BufRead *.tt setf tt2html
augroup END