Ruby/Rails勉強会@関西-19に参加しました

以下メモです。

ScalaからみたRuby by 西本さん

  • Z80のハンドアセンブル経験者。機械語は必須じゃない。
  • スカラー波ではなく。The Scala Programmig Language。概要はPower of Scala参照。
  • 特徴。バージョン2.6.0。近代的な言語。JVMや.Netで動作(Mono含む)。Java、.NetのAPIやライブラリを直接呼び出し。Java ME CLDC対応。インタプリタコンパイラも存在します。型を生かすための豊富な文法。Actorなどの便利機能。Perser Combinatorによる内部言語。EDSL。
  • 感想。かなりの変態言語。便利な機能満載だが、かなりカオス(シンプルじゃない)。ライブラリが言語機能を拡張。
  • 国内の人口。10人くらい?そんなの関係ねぇ。
  • 文法の比較。型付け、型推論の代入。var。val(再代入できない)。条件分岐は似たようなもの。for文、イテレータ。untilはその値が入らない。toは入る。yieldは無名関数? filterも書ける。んー、リスト内包表記ぽい。メソッド、クラスも似たようなもの。Scalaのobject Foo {...}はSingleton Object。ScalaのTrait。インスタンス化はできない。実装は書いておける。他のクラスに継承させる。Rubyのmoduleみたいなもの。Scalaの関数オブジェクト。Rubyは。f.call(...)と書かないといけない。関数ぽくない。例外は似たようなもの。ScalaのPackage。名前空間を分ける。Scalaのimport。名前を省略できる。Javaぽい。Scalaの暗黙の型変換。Implicit parameters。うげ。直感的にこれは恐いような気がする。Scalaのパターンマッチ。Case Class。んー、Haskellと比べると面倒くさい気がする。Scalaの遅延評価。ほう。こんなのまだあるんだ。ScalaGenerics。コレクションなどのパラメータに型付けする総称型。ScalaのStructural subtyping。Duck Typingぽいことができる。ScalaXMLリテラルとして使える。すげー。テンプレートとしても使える。DOMツリーが返る。Scalaアノテーションメタプログラミングのためのタグ付け。Javaのとは若干意味が違う。ScalaのCompilerで拡張できる。ScalaのParser Combinator。PEGベースで字句解析・構文解析ができる。ScalaのActor。並行処理。Erlang由来。手続きを並行化する機構。プロセスやスレッドよりも軽量とされる。自動的に切り替わらない。RubyのFiber。1.9から。実験段階。
  • ライブラリ、API
  • メタプログラミング。手法。1.マクロ。CのプリプロセッサLispのマクロ。2.自動生成。XSLTシンタックスシュガーも含む。3.DSLシェルスクリプトWiki記法。Parser。ExcelVBAScalaはJavaBeansを作るアノテーション。Rubuのアクセサ。XMLテンプレート。Railsのscaffold。
  • 性能。Scalaの方がだいぶ早い(1桁、2桁。マイクロベンチマーク)。メモリ使用量はRubyの方が少ない。
  • Web開発環境。RubyRailsとか。Lift Web Framework。Railsぽい。
  • まとめ。Scalaはちょっととっつきにくい言語。
  • 質疑応答。海外では注目されている。どういう分野で使われているか? まだまだユーザが少なくてよくわからない。

Railsを教える順序 by 石川さん

  • 教育者の思考停止。どうしてこの順序で教えるんですか? 私がこの順序で教わったからだ。技巧的な因数分解→解の公式。微分積分。直感的な極限→ε-δ(→超実数)。
  • C言語至上主義。C++を学ぶ前にCの知識が必要である。思い付く限りの回り道をさせているとしか思えない。
  • 初心者には(C言語の例)。floatの代わりにdoubleだけで充分じゃない? 共用体なんて教えなくてもいいんじゃない? 文字型配列の代わりに文字列クラスで充分じゃない?(Cはなくても他の言語には大抵ある。)
  • チャットが忙しい。
  • 教える順序と認識。if…else…end。最初にelseをつけて教えるか?
  • MVCをどう教えるか。ゲームとか分かりやすい例で説明した方がいい。viewの説明をmixiで。
  • 永続化をdefault意識に。
  • Mから作るかCから作るか。んー、いろいろ意見が分かれそう。MのないVCなんて虚しい。
  • 初心者には重要なフォルダを先に教えるべき。
  • helperの存在意義。
  • 到達目標の設定。どこまで教えたらRails入門と言えるか。主観か。1対他の関係を作るところまで教えられないか。
  • testは? 初学者に教えるべきか?
  • セキュリティも。これもtestと同じ。
  • Rails検定があったらいいかな。教育機関の内部にはあったらいいかな。
  • Rails学習者のスタンダード。blog。mixi。他には?

Rubyリファレンスマニュアル刷新計画進捗報告 by okkezさん

  • るびま21号は今朝リリースされました。
  • 今までの流れ。第一段階。2006/10/12完了。第二段階。2007/01/08完了。
  • 第三段階。作業中。締切は明日。進捗率は65%(今朝の6時過ぎの段階)。
  • 人材募集中。

How to Use "Kagemusha" by 氏久くん

  • Kagemusha。テストを助けてくれるライブラリ。モックオブジェクト関係。
  • Rubyは動的でいろいろ上書きできるけど、それをある範囲に限定する。
  • ポイントフリースタイルっぽいところがいい。

Ruby初級者レッスン第14回 by okkezさん、サカイさん

二次会

  • Emacszshの設定ファイル。見せてくれと言われたので以下に貼っておきます。

ファイル: .zshrc

# -*- shell-script -*-
# ===================
#  shell config file
# ===================
#
#  since Sun Sep 30 17:54:34     2007
#

stty erase ^H

export_if_exist()
{
    local realvar="$3"
    [ X"$realcmd" = X ] && realvar="$2"

    local p
    for p in `echo $PATH | tr : ' '`; do
        if [ -e "$p/$2" ]; then
            export "$1"="$realvar"
            break
        fi
    done
}

export PATH_ORIG="$PATH"
export PATH="$HOME/bin"
export PATH="$PATH:/cygdrive/c/Program Files/erl5.5.4/bin"
export PATH="$PATH:/cygdrive/c/usr/apps/upx201w"
export PATH="$PATH:/cygdrive/c/Program Files/ruby-1.8/bin"
export PATH="$PATH:/cygdrive/c/usr/apps/href-0.3.2"
export PATH="$PATH:/cygdrive/c/usr/apps/glo51wb/bin"
export PATH="$PATH:/cygdrive/c/usr/apps/darcsdir-w32"
export PATH="$PATH:/usr/local/bin:/usr/local/sbin"
#export PATH="$PATH:/usr/pkg/bin:/usr/pkg/sbin"
export PATH="$PATH:/bin:/sbin:/usr/bin:/usr/sbin"
export PATH="$PATH:/usr/X11R6/bin:/usr/games"
#export PATH="$PATH:/opt/bin:/opt/rubygems/bin"
[ `uname` = CYGWIN_NT-5.1 ] && export PATH="$PATH:$PATH_ORIG"

export EDITOR=vi
export PAGER=less
export_if_exist PAGER lv
export_if_exist PAGER jless
export BLOCKSIZE=K
export INPUTRC=~/.inputrc
if [ `uname` = CYGWIN_NT-5.1 ]; then
  export LANG=C
  export LC_CTYPE=C
  export LC_TIME=C
else
  export LANG=ja_JP.eucJP
  export LC_CTYPE=ja_JP.eucJP
  export LC_TIME=C
fi
#export WWW_HOME=http://127.0.0.1/memo/
[ `uname` = NetBSD ] && export LSCOLORS=6050202030404032346464
[ `uname` = FreeBSD ] && export export LSCOLORS=gxfxcxdxbxegedabagacad
export CLICOLOR=true
export PERL_BADLANG=true
export CVS_RSH=ssh
#export RUBYLIB=/opt/lib/ruby/site_ruby/1.8/
#export GEM_HOME=/opt/rubygems/

#export http_proxy=http://localhost/

#export UIM_CANDWIN_PROG=uim-candwin-gtk
#export XMODIFIERS=@im=uim

if [ `uname` = CYGWIN_NT-5.1 ]; then
  HOST=`hostname`
else
  HOST=`hostname -s`
fi
PS1='$USER@$HOST(!) '
SPECIAL_PS1=true

HISTSIZE=10000
HISTFILE=~/.history

alias_if_exist()
{
    local realcmd="$3"
    [ X"$realcmd" = X ] && realcmd="$2"

    local p
    for p in `echo $PATH | tr : ' '`; do
        if [ -e "$p/$2" ]; then
            alias "$1"="$realcmd"
            break
        fi
    done
}

alias_if_exist ls colorls 'colorls -F -G'
[ `uname` = FreeBSD ] && alias ls='ls -F -G'
alias ll='ls -l'
alias la='ls -la'

alias rm='rm -i'
#alias_if_exist rm saferm
#alias rm=saferm
alias mv='mv -i'
alias cp='cp -i'

alias md=mkdir
alias rd=rmdir

alias sl=ls
alias eixt=exit

alias less=$PAGER
alias df='df -m'

alias reboot='sudo reboot'
alias poweroff='sudo shutdown -p now'
alias zzz='sudo pkill pppd; sleep 3; sudo zzz'

alias xinit='xinit -- -ar1 200 -ar2 20'
alias xxinit='BIG=true \xinit -- -ar1 200 -ar2 20 -depth 16'  

alias reload='. ~/.profile'
alias config='vi ~/.profile'
alias reloadz='. ~/.zshrc'
alias configz='vi ~/.zshrc'

alias rmbak='rm -f *~; rm -f *.bak'

alias_if_exist man w3mman
alias_if_exist refe w3mrefe
alias_if_exist ftp lftp
alias_if_exist ping gwping

alias tod='printf "%d\n"'
alias tox='printf "0x%x\n"'

saferm()
{
    local trash=`date +$HOME/.trash/%Y%m%d`

    while [ $# -gt 0 ]; do
	case "$1" in
	    --) shift; break;;
	    -*) shift;;
	    *) break;;
	esac
    done

    if [ $# -eq 0 ]; then
	echo "usage: saferm file..."
	return 1
    fi

    /bin/mkdir -p "$trash"
    [ -d "$trash" ] || return 1

    while [ $# -gt 0 ]; do
	/bin/mv -f -- "$1" "$trash"
	shift
    done
}

mdcd()
{
    mkdir -p "$1"
    cd "$1"
}

ndir()
{
    local n=`/bin/ls | grep -e '^[0-9][0-9]*$' | sort -n | tail -1`
    [ "$n" = "" ] && n=0
    printf "%02d\n" `expr $n + 1`
}

ndcd()
{
    local dir=`ndir`
    mkdir -p $dir
    cd $dir
}

ddcd()
{
    local dir=`date +%m%d`
    mkdir -p $dir
    cd $dir
}

PS0='$ '
RPS0=
px()
{
    if [ X"$SPECIAL_PS1" = Xtrue ]; then
	unset SPECIAL_PS1
    else
	SPECIAL_PS1=true
    fi
    local tmp
    tmp="$PS1"; PS1="$PS0"; PS0="$tmp";
    tmp="$RPS1"; RPS1="$RPS0"; RPS0="$tmp";
}

if [ X"$KSH_VERSION" != X ]; then
    set -o emacs
    bind '^I=complete'
    bind '^I^I=complete-list'
    bind '^V=quote'
    bind -m '^[u=^Ucd ..^M'
    bind -m "^[o=| $PAGER^M"

elif [ X"$BASH_VERSION" != X ]; then
    PS1='hoge$ '
    bind 'Meta-u:" \C-ucd ..\n"'
    bind '"\M-u":" \C-ucd ..\n"'
    bind 'Meta-o:"| $PAGER\n"'
    bind '"\M-o":"| $PAGER\n"'

elif [ X"$ZSH_VERSION" != X ]; then
    autoload -U compinit
    compinit -u
    compdef -d w3m
    
    bindkey -e
    bindkey -s '\M-u' '^Ucd ..\n'
    bindkey -s '\eu' '^Ucd ..\n'
    bindkey -s '\M-o' "| $PAGER^M"
    bindkey -s '\eo' "| $PAGER^M"
    
    p=/usr/pkgsrc/
    s=/usr/src/

    PS1=$'%~\n%{^[[32;40;1m%}%n@%m(%!)%{^[[0m%} '        # ← ^[をEscに置き換えてください。
    RPS1='%{^[[32;40;1m%}%D{%Y/%m/%d %H:%M:%S}%{^[[0m%}' # ← ^[をEscに置き換えてください。
    SAVEHIST=$HISTSIZE
    HISTFILE=~/.zhistory
    
    setopt hist_ignore_all_dups
    setopt hist_reduce_blanks
    setopt share_history
    setopt auto_cd
    setopt cdable_vars
    setopt correct
    setopt no_beep
    setopt menu_complete
    
    zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' 'r:|[.,_-]=* r:|=*' 'l:|=* r:|=*'

    alias -g O="| $PAGER"
else
    set -E emacs
fi

[ -f "$HOME/.profile_$HOST" ] && . "$HOME/.profile_$HOST"

unset ENV
# end

ファイル: .emacs

;; ====================
;;  Meadow config file
;; ====================
;;
;;  since Sat Mar 17 00:00:06 +0900 2007
;;

(defmacro eval-safe (&rest body)
  `(condition-case err
       (progn ,@body)
     (error (message "[eval-safe] %s" err))))

;; global key binding
(global-unset-key "\C-q") 
(global-set-key "\C-q\C-q" 'quoted-insert)
(global-set-key "\C-xn"	   'next-error)
(global-set-key "\C-h"	   'backward-delete-char-untabify)
(global-set-key "\C-u"	   'advertised-undo)
(global-set-key "\M-c"	   'compile)
(global-set-key "\M-u"	   'universal-argument)

;; register 
(set-register ?f '(file . "c:/Documents and Settings/s-tanaka/デスクトップ"))
 
;; misc 
(set-language-environment 'Japanese)

(setq fill-column -1)
(setq kill-whole-line t)
(setq scroll-step 1)
(setq blink-matching-delay 0.2)
(setq inhibit-startup-message t)
(transient-mark-mode t)
(menu-bar-mode 0)
(tool-bar-mode 0)
(scroll-bar-mode -1)
(fset 'yes-or-no-p 'y-or-n-p)
(column-number-mode t)
(setq mouse-yank-at-point t)
(setq visible-bell t)
(setq ring-bell-function '(lambda ()))
(put 'upcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)

;; face 
(eval-safe 
 (require 'color-theme)
 (color-theme-initialize)
 (color-theme-robin-hood))

(w32-add-font
 "fixedsys"
 '((spec
    ((:char-spec ascii :height any)
     strict
     (w32-logfont "FixedSys" 0 16 400 0 nil nil nil 128 1 1 1))
    ((:char-spec ascii :height any :weight bold)
     strict
     (w32-logfont "FixedSys" 0 16 800 0 nil nil nil 128 1 1 1)
     ((spacing . -1)))
    ((:char-spec ascii :height any :slant italic)
     strict
     (w32-logfont "FixedSys" 0 16 400 0 nil nil nil 128 1 1 1))
    ((:char-spec ascii :height any :weight bold :slant italic)
     strict
     (w32-logfont "FixedSys" 0 16 800 0 nil nil nil 128 1 1 1)
     ((spacing . -1)))
    ((:char-spec japanese-jisx0208 :height any)
     strict
     (w32-logfont "FixedSys" 0 16 400 0 nil nil nil 128 1 1 1))
    ((:char-spec japanese-jisx0208 :height any :weight bold)
     strict
     (w32-logfont "FixedSys" 0 16 800 0 nil nil nil 128 1 1 1)
     ((spacing . -1)))
    ((:char-spec japanese-jisx0208 :height any :slant italic)
     strict
     (w32-logfont "FixedSys" 0 16 400 0 nil nil nil 128 1 1 1))
    ((:char-spec japanese-jisx0208 :height any :weight bold :slant italic)
     strict
     (w32-logfont "FixedSys" 0 16 800 0 t nil nil 128 1 1 1)
     ((spacing . -1))))))

(create-fontset-from-request "tt-font"
			     '((width . 16)
			       (height . 32)
			       (fixed . t)
			       (weight . 800)
			       (italic . nil))
			     '((family . "Courier New")
			       (family . "MS ゴシック")))

(set-face-attribute 'variable-pitch nil :family "*")
(setq default-frame-alist
      (append '((font   . "fixedsys")
		(width  . 116)
		(height .  45)
		(top    .   0)
		(left   .   0))
	      default-frame-alist))

;; dabbrev 
(setq dabbrev-case-fold-search nil)
(setq dabbrev-abbrev-char-regexp "\\w\\|\\s_")

;; auto-mode  
(setq auto-mode-alist
      (append '(("\\.rb$"  . ruby-mode))
	      auto-mode-alist))

;; auto-insert 
(load "autoinsert")
(setq auto-insert-alist 
      (append '((ruby-mode . (lambda () (insert "#!/usr/bin/env ruby\n\n")))
		(html-mode . (lambda () (sgml-tag "pre"))))
	      auto-insert-alist ))
(add-hook 'find-file-hooks 'auto-insert)

;; minibuffer  
(defun minibuffer-delete-path-backward ()
  (interactive)
  (delete-region (point) (progn (forward-word -1) (point))))

(add-hook
 'minibuffer-setup-hook
 '(lambda ()
    (local-set-key "\C-w" 'minibuffer-delete-path-backward)))

;; dired
(add-hook
 'dired-mode-hook
 '(lambda ()
    (define-key dired-mode-map "U" 'dired-up-directory)))
(setq dired-listing-switches "-l")

;; cc-mode
(add-hook
 'c-mode-common-hook
 '(lambda ()
    (c-set-style "CC-MODE")
    (setq tab-width 8)
    (setq c-basic-offset 4)    
    (define-key c-mode-map "\C-cp" 'c-insert-printf)
    (define-key c-mode-map "\C-cf" 'c-insert-for)
    (modify-syntax-entry ?_ "w")
    (font-lock-add-keywords 'c-mode '("\\<\\(TRUE\\|FALSE\\)\\>"))
    (setq c-font-lock-extra-types '("FILE" "\\sw+_t"))))

(defun c-insert-printf()
  (interactive)
  (c-indent-command)
  (insert "printf(\"")
  (let ((p (point)))
    (insert "\")\;")
    (goto-char p)))

(defun c-insert-for()
  (interactive)
  (c-indent-command)
  (insert "for (i = 0; i < ")
  (let ((p (point)))
    (insert "; i++) {\n")
    (insert "}")
    (c-indent-command)
    (goto-char p)))

;; ruby-mode
(autoload 'ruby-mode "ruby-mode" "Mode for editing ruby source files")
(setq interpreter-mode-alist
      (append '(("^#!.*ruby" . ruby-mode)) interpreter-mode-alist))
(setq ruby-deep-indent-paren nil)

(add-hook
 'ruby-mode-hook
 '(lambda ()
    (define-key ruby-mode-map "\C-cb" 'ruby-insert-block)
    (define-key ruby-mode-map "\C-cB" 'ruby-insert-block2)
    (define-key ruby-mode-map "\C-ci" 'ruby-insert-escape)
    (define-key ruby-mode-map "\C-co" 'ruby-insert-open)
    (define-key ruby-mode-map "\C-cp" 'ruby-insert-print-line)))

(defun ruby-insert-block ()
  (interactive)
  (ruby-indent-command)
  (insert "do |")
  (let ((p (point)))
    (insert "|\n end")
    (ruby-indent-command)
    (goto-char p)))

(defun ruby-insert-block2 ()
  (interactive)
  (ruby-indent-command)
  (insert "{|")
  (let ((p (point)))
    (insert "| }")
    (goto-char p)))

(defun ruby-insert-escape ()
  (interactive)
  (insert "#{")
  (let ((p (point)))
    (insert "}")
    (goto-char p)))

(defun ruby-insert-open ()
  (interactive)
  (insert "open('")
  (let ((p (point)))
    (insert "', 'r') ")
    (ruby-insert-block)
    (insert "file")
    (goto-char p)))

(defun ruby-insert-print-line ()
  (interactive)
  (ruby-indent-command)
  (insert "print \"") 
  (let ((p (point)))
    (insert "\\n\"")
    (goto-char p)))

;; haskell-mode
(eval-safe
 (load "haskell-mode-2.3/haskell-site-file")
 (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
 (add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
 (add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent))

;; text-mode
(add-hook
 'text-mode-hook
 '(lambda ()
    (auto-fill-mode 0)
    (define-key text-mode-map "\C-cb" 'text-insert-hatena-code-block)
    (define-key text-mode-map "\C-cl" 'text-insert-line)))

(defun text-insert-line ()
  (interactive)
  (insert "----\n"))

(defun text-insert-hatena-code-block ()
  (interactive)
  (insert ">||\n||<\n")
  (previous-line 1))

;; html-mode (for predoc)
(define-skeleton html-href-anchor2
  "HTML anchor tag with href attribute."
  "URL: "
  "<a href=\"" str "\">" _ "</a>")
(setq html-mode-hook
      '(lambda ()
	 (local-set-key "\C-c\C-ch" 'html-href-anchor2)))

;; skk
(eval-safe 
 (require 'skk-leim)
 (setq default-input-method "japanese-skk")
 (require 'skk-vars)
 (global-set-key "\C-xj" 'skk-mode)
 (setq skk-set-henkan-point-key
       (append '(?:) skk-set-henkan-point-key))
 (setq skk-downcase-alist
       (append '((?: . ?\;)) skk-downcase-alist))
 (setq skk-rom-kana-rule-list
       (append
	'((";" nil ("ッ" . "っ"))
	  ("x;" nil ";")
	  ("la" nil ("ァ" . "ぁ"))
	  ("li" nil ("ィ" . "ぃ"))
	  ("lu" nil ("ゥ" . "ぅ"))
	  ("le" nil ("ェ" . "ぇ"))
	  ("lo" nil ("ォ" . "ぉ"))
	  ("lya" nil ("ャ" . "ゃ"))
	  ("lyu" nil ("ュ" . "ゅ"))
	  ("lyo" nil ("ョ" . "ょ")))
	skk-rom-kana-rule-list)))

;; dabbrev
(eval-safe (require 'dabbrev-highlight))

;; memo
(setq user-full-name "TANAKA Shin-ya")
(setq user-mail-address "tanaka.shinya@gmail.com")
 
(setq memo-tmp-dirname "~/memo/")
(setq memo-tmp-format "%Y/h%m-%d.txt")
(setq memo-filename "~/memo/ch2004.txt")

(add-hook
 'change-log-mode-hook 
 '(lambda ()
    (set (make-local-variable 'add-log-time-format) 
	 'add-log-iso8601-time-string-with-weekday)))
 
(global-set-key "\C-q\C-w" 'memo-tmp-open-today)
(defun memo-tmp-open-today (arg)
  (interactive "P")
  (let ((today-file
	 (concat memo-tmp-dirname 
		 (format-time-string memo-tmp-format))))
    (find-file today-file)))

(global-set-key "\C-xM" 'memo)
(defun memo ()
  (interactive)
  (add-change-log-entry
   nil
   (expand-file-name memo-filename)))

(global-set-key "\C-xm" 'memo-open)
(defun memo-open ()
  (interactive)
  (find-file memo-filename)
  (change-log-mode))

(defun add-log-iso8601-time-string-with-weekday ()
  (let ((system-time-locale "C"))
    (concat (add-log-iso8601-time-string)
            " " "(" (format-time-string "%a") ")")))

;; browse-url
(setq thing-at-point-url-path-regexp
      "[^]\t\n \"'()<>[^`{}]*[^]\t\n \"'()<>[^`{}.,;]+")

(setq thing-at-point-url-regexp
      (concat
       "\\<\\(h?t?tps?://\\|ftp://\\|gopher://\\|"
       "telnet://\\|wais://\\|file:/\\|s?news:\\|mailto:\\)"
       thing-at-point-url-path-regexp))

(setq browse-url-browser-function '(("." . browse-url-firefox)))
(setq browse-url-firefox-program "c:/Program Files/Mozilla Firefox/firefox.exe")
(defun browse-url-firefox (url &optional new-window)
  (interactive (browse-url-interactive-arg "URL: "))
  (if (string-match "^t?tp://" url)
      (setq url (concat "http://" (substring url (match-end 0)))))
  (if (string-match "^t?tps://" url)
      (setq url (concat "https://" (substring url (match-end 0)))))
  (start-process (concat browse-url-firefox-program url) nil 
		 browse-url-firefox-program "-remote" 
		 (concat "openurl(" url ", new-tab)")))

;; hatena
(defun hatena-convert-url-to-id ()
  "カーソル付近のURLをはてなID記法に変換する。"
  (interactive)
  (let ((bounds (bounds-of-thing-at-point 'url)))
    (if bounds
	(let* ((beg (car bounds))
	       (end (cdr bounds))
	       (urls (split-string (buffer-substring beg end) "/"))
	       (user (nth 3 urls))
	       (date (nth 4 urls))
	       (item (nth 5 urls))
	       (idstr (concat "id:" user)))
	  (if (and date (not (string-equal date "")))
	      (setq idstr (concat idstr ":" date)))
	  (if (and item (not (string-equal item "")))
	      (setq idstr (concat idstr ":" item)))
	  (delete-region beg end)
	  (insert idstr)))))

;; indent-and-next-line
(global-set-key "\M-n" 'indent-and-next-line)
(fset 'indent-and-next-line "\C-i\C-n")

;; insert-arrow
(global-set-key "\M-'" 'insert-arrow)
(fset 'insert-arrow "->")

;; trim-buffer
(defun trim-buffer ()
  "Delete excess white space."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "[ \t]+$" nil t)
      (replace-match "" nil nil))
    (goto-char (point-max))
    (delete-blank-lines)
    (mark-whole-buffer)
    (tabify (region-beginning) (region-end))))

;; erlang
(setq load-path (cons  "C:/Program Files/erl5.5.4/lib/tools-2.5.4/emacs" load-path))
(setq erlang-root-dir "C:/Program Files/erl5.5.4")
(setq exec-path (cons "C:/Program Files/erl5.5.4/bin" exec-path))
(require 'erlang-start)

(require 'compile)
(add-to-list 'compilation-error-regexp-alist
             '(".+\\[\\(.+\\):\\([0-9]+\\)\\]:" 1 2))
;; end