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の遅延評価。ほう。こんなのまだあるんだ。ScalaのGenerics。コレクションなどのパラメータに型付けする総称型。ScalaのStructural subtyping。Duck Typingぽいことができる。ScalaはXMLがリテラルとして使える。すげー。テンプレートとしても使える。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。ExcelのVBA。ScalaはJavaBeansを作るアノテーション。Rubuのアクセサ。XMLテンプレート。Railsのscaffold。
- 性能。Scalaの方がだいぶ早い(1桁、2桁。マイクロベンチマーク)。メモリ使用量はRubyの方が少ない。
- Web開発環境。RubyはRailsとか。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さん、サカイさん
二次会
ファイル: .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