Head First Cの感想

以前参加したmrubyの勉強会でC言語でコードを書く機会があってよくわからなかったので、オススメされた「Head First C」を読んでみた。

Head First C ―頭とからだで覚えるCの基本

Head First C ―頭とからだで覚えるCの基本

500ページ超あるんだけどすごくわかりやすくて10日間で読み終わった。Head FirstシリーズはRailsなどいろいろあるのは知ってたけど読んだことなかった。どうやらこのシリーズは科学的なアプローチで分かりやすく書いているみたいで、確かにわかりやすかった。C言語の入門書というとすごい古い本や固っくるしい本が多いような印象があるけど、この本は今月発売されたばかりでかつカジュアルだったので、とっかかりやすかった。

内容はmain()とかポインタから始まって、最後はマルチプロセスのwebサーバーを作ったりマルチスレッドプログラミングを扱うところまでカバーしてる。やっぱりポインタが鬼門で、何度も読み返したけど80%くらいの理解。文字列ポインタとか配列変数とかで???ってなった。それ以外は本当にわかりやすくてよかった。特にメモリ管理のところはわかりやすかった。普段Rubyとか書いてるとあまりメモリのことは考えないけど、スタックとヒープの区別がついたり、valgrindを使ってメモリリークを調べたりすることでだいぶメモリに対する意識が高まった。また、gccでコンパイルしたりリンクをひとつひとつ丁寧にやることでmakeの有難みを感じた。iOSアプリを開発するとたまに出てくるスタティックリンクライブラリ(lib*.aみたいなの)の正体もわかってよかったし、今後iOSアプリのビルドに失敗しても怯えなくて済みそう。あと、途中のコラムでOpenCVについて簡単な説明があってちょっと興味がわいてきた。Raspberry Piとウェブカメラを買ってOpenCVで遊んでみたいと思った。

vimでTodoリスト

今までいろんなTodo管理アプリを試してきたけど、「GUIアプリほど高機能はいらない」「ターミナル上でtodoを確認したい」という理由でvimでTodoリストを書くようになった。これによるとGithubがGithub Flavored MarkdownにTodoリスト記法を実装したようなので、これに倣ってmarkdownでTodoリストを書くことにした。

todoコマンド

まず、Todoリストを開くコマンドをaliasで定義してみた。これでtodoでTodoリストを確認できる。さらに、Dropbox上にファイルを置けば複数PCで共有できるので、オフィスのPCとプライベートPCでTodoリストを共用できる。

# .zshrc

if [ -e "$HOME/Dropbox" ]; then
  alias todo="$EDITOR $HOME/Dropbox/.todo.md"
else
  alias todo="$EDITOR $HOME/.todo.md"
end

vimでmarkdownを書く準備

次に、vimでmarkdownを書く準備をする。普通に*.mdを開くとmodula2というfiletypeで認識されてしまい、markdownファイルとして見なされないので、便利プラグインをインストールする。

" .vimrc

NeoBundle 'tpope/vim-markdown'

折り返しを有効にする

これだけでも十分なんだけど、より使いやすくするための設定を自分なりに考えてみた。まず、一行が長くなるとリストとしては見づらいので、普段は折り返さないけどmarkdownのときだけ折り返すようにしてみた。

" .vim/ftplugin/markdown.vim

" 折り返しを有効にする
set wrap

" 80文字で折り返す
set textwidth=80

" マルチバイト文字の場合も折り返しを有効にする
set formatoptions+=m

Todoリストを簡単に書く

上でふれたGithubが実装したTodoリスト記法- [ ], - [x]を簡単に入力するための設定も書いた。abbreviateを使うと略記を登録することができる。下の設定ではtl<space>と入力すると- [ ]と自動的に変換される。さらに、Todoリストのある行の上で<Leader>を2回おすと(僕は<Leader><space>にしてる)、チェックをon/off切り替えられる。

" .vim/ftplugin/markdown.vim

" todoリストを簡単に入力する
abbreviate tl - [ ]

" todoリストのon/offを切り替える
nnoremap <buffer> <Leader><Leader> :call ToggleCheckbox()<CR>

function! ToggleCheckbox()
  let l:line = getline('.')
  if l:line =~ '^\-\s\[\s\]'
    let l:result = substitute(l:line, '^-\s\[\s\]', '- [x]', '')
    call setline('.', l:result)
  elseif l:line =~ '^\-\s\[x\]'
    let l:result = substitute(l:line, '^-\s\[x\]', '- [ ]', '')
    call setline('.', l:result)
  end
endfunction

スクリーンショット

普段は下のようにtmuxで画面を分割して小さいウィンドウ(右上)にTodoリストを表示しながら開発している。

f:id:naoty_k:20130428002301p:plain

vimプラグインを作ってみた

はじめてvimプラグインというものを作ってみた。コメントを折りたためるようにするだけ。zm, zrなどで表示/非表示を切り替えられる。NeoBundleでインストールすればそのまま使える。

naoty/vim-folcom · GitHub

金曜日にmrubyの勉強会にいって、build_config.rbの大量のコメント(デフォルト値のコメントアウト)を見てウッとなって、コメントだけ非表示にできないか調べてみたら意外に簡単にできた & 手頃なプラグインがなかったので作ってみた。

コメントって読む人が初心者の場合はとても助かるけど、分かってる人にとっては邪魔なだけだから、コメントを読む人が表示/非表示を切り替えられた方がいいと思った。分かってる人には邪魔だろうなと思ってコメント書かないと初心者は困ってしまうので、読む側がコメントを見るかどうかを判断すればいいと思う。そしたら、コメント書く側は初心者のことを考えてコメントを書くようになるんじゃないかと思う。


参考

vimの便利機能

入力補完

  • インサートモードで<C-n>または<C-p>と打つと、補完候補が出てきます。

バッファ

  • 新しいファイルを開くと、バッファという領域にその中身が読み込まれます。過去に開いたファイルをまた開くときに便利です。
  • 直前に開いたファイルに戻りたい場合によく使います。
  • 個人的には、前後のバッファに移動したりバッファから履歴を削除するために以下のようなマッピングを設定しています。
nnoremap <Tab>     :bnext<CR>
nnoremap <S-Tab>   :bprevious<CR>
nnoremap <Leader>d :bdelete<CR>
  • これでTabやShift+Tabで前後のバッファに移動できます。

タブ

  • vimにもブラウザのようなタブがあります。同時に多くのファイルを開きたいときによく使います。
  • デスクトップPCであまり画面が大きくない場合、分割して複数のファイルを開くよりタブの方が出番が多いような気がします。
  • 個人的には、前後のタブに移動したり新しいタブを開くために以下のようなマッピングを設定しています。
nnoremap <Leader>t :tabnew<CR>
nnoremap <Leader>n :tabnext<CR>
nnoremap <Leader>p :tabprev<CR>

コマンド定義

  • 文字コードを変換したりインデント量を変更する操作はけっこうやるので、自分でコマンドを定義して一発で操作できるようにするとラクですね。
command! Indent2 :setlocal tabstop=2 shiftwidth=2
command! Indent4 :setlocal tabstop=4 shiftwidth=4
command! ToSjis :e ++enc=sjis<CR>
  • これで普通に:Intent2と打てばインデント量が2になります。
  • 基本はcommand! <Command name> <command>です。コマンド名は大文字から始めなくちゃいけないようです。あとはいろいろオプションがあるので、詳しくは:help command-nargsを見てください。

abbreviate

  • abbreviateは長くてめんどくさい表記に略を設定できる機能です。
abbreviate #i #include
  • 例えば上のように設定すると、"#i[space]"と入力すると勝手に"#import[space]"と変換してくれます。あとはコメントブロックを入力するのによく使われるみたいです。
abbreviate #b /****************************
  • abbreviateは応用としてtypoを修正するのにも便利です。"abbreviate"っていう単語がもうtypoしそうですね。あと、個人的に"receive"を"recieve"と書いてしまうことが多いので以下のように設定します。
" abbreviate <誤> <正>
abbreviate abbriviate abbreviate
abbreviate recieve receive
  • abbreviateの設定をそのまま.vimrcに書くと、ハードコーディング感があって個人的に気持ち悪いので、.vim/abbreviate.vimという別ファイルに分けて書いてます。
" .vim/abbreviate.vim
abbreviate abbriviate abbreviate
abbreviate recieve receive

" .vimrc
source ~/.vim/abbreviate.vim

filetype毎の設定ファイル

  • 言語によってインデント量を変えたいってケースはほとんどのvimmerにあると思うんですが、そういうときに僕はfiletype毎の設定ファイルを用意しています。
  • インデント量だけならautocmdを使うのもアリだと思うのですが、上のabbreviateで設定したコメントブロックのように言語によって細かく設定を変えたいケースが地味にあるので、設定ファイルを用意する方法を採っています。
.vim
|- ftdetect
    |- filetype.vim
|- ftplugin
    |- javascript.vim
    |- make.vim
    |- ruby.vim
.vimrc
  • 上のようなディレクトリ構造にしておくと、各filetypeごとに設定ファイルが読み込まれるようになります。詳しくは:help filetype-pluginらへんを見てください。
  • 例えばMakefileを書く場合、インデントはspaceではなくtabしか使えないので、expandtabを無効にしたいところです。そこで、以下のようなファイルを用意します。
" .vim/ftplugin/make.vim
setlocal noexpandtab
setlocal tabstop=8
setlocal shiftwidth=8

filetypeの指定

  • Gemfileなど拡張子では判別できないファイルのfiletypeを指定したい場合、ftdetectが便利です。
.vim
|- ftdetect
    |- filetype.vim
.vimrc
" .vim/ftdetect/filetype.vim

autocmd BufRead,BufNewFile Gemfile    setfiletype ruby
autocmd BufRead,BufNewFile Guardfile  setfiletype ruby
autocmd BufRead,BufNewFile *.rabl     setfiletype ruby
autocmd BufRead,BufNewFile *.jbuilder setfiletype ruby
autocmd BufRead,BufNewFile *.ru       setfiletype ruby
  • 上のように設定ファイルを用意すると、指定したファイルを自動的にrubyをfiletypeとして開いてくれます。

以上の設定はすべて僕のdotfilesに書いてあるので参考にしてみてください。

読み返してみると、その筋の方に怒られそうな気がしてきた…(´・ω・`)

退職のお知らせ

3月末をもって、アルバイトの頃から約2年ほど勤めていた会社を退職することになりました。アルバイトの頃はRailsでサーバーサイドの開発を担当し、大学卒業後は正社員としてAndroidアプリとiOSアプリの開発を担当しました。未経験の自分にアプリ開発を任せていただけて、いろいろな面で勉強させていただきました。

4月からは、これまでとは違うフィールドで働く予定です。偶然に偶然が重なって(このブログもきっかけの一つ)、以前から興味のあった領域に携われることになり、この度転職を決意しました。これまた未経験の領域に飛び込むことになるので、これから必死に勉強する必要がありそうです。ですが、この約2年間でずいぶんと未知の領域にチャレンジしてきたので、その経験と身につけた自信でこれからも頑張っていけそうです。

これまでお世話になった皆様、有難うございました。今後とも宜しくお願い致します。

人間の脳みその限界とツールについて

複数の設定があり、それらの組み合わせによって挙動が変わるアプリを書いていると、だんだんそれぞれの組み合わせについて頭がこんがらがってくる。コードを修正するたびにそれぞれの組み合わせについて、どのように影響が出るか考えなければならなくて、つらくなってくる。つらいだけでなく、確実にミスが生まれる。

こういう状況が続くと、人間の脳みその処理能力について限界を感じてくる。人間はこういうことに向いていないと思うようになる。人力によるチェックにも自信が持てなくなる(そして、それでいいのだと思うようになる)。人間の脳みそに限界を感じるようになると、ツールに頼りたくなってくる。限界を感じることで自分自身に対して謙虚になり、ツールの使い所を実感するんだと思う。

例えば、脳内で多数の組み合わせをシミュレーションするのをやめてプログラムにテストさせるとか、手でひとつひとつ丁寧にメソッド名を置換するのをやめて、Eclipseに任せるとか。何度も同じコマンドを手打ちするのをやめてシェルの補完を使うとか。あと、publicなメソッド・プロパティを必要最小限にすれば、そのクラスを使う人は考えることが減るんだから、public/privateという概念も脳みその負荷を減らす工夫なのかもしれない。

とにかく、脳に強いストレスを感じたら、たぶんその作業は人間には向いていないと思うので、ツールに任せられないか一回検討した方がいいと思う。もっと自分の脳みその能力を疑った方がいいと思う。

Arduinoと感圧センサーで圧力をサーバーに送信する

秋葉原の秋月電子に行って、慣れない雰囲気の中、なんとかこの感圧センサーをゲットしました。

オライリーPrototyping Labという本を見ながら回路を接続して、上のようなプログラムを実行するとこんな感じになりました。

f:id:naoty_k:20130123235951g:plain

センサーに加わった圧力を0番のアナログピンから受け取り、シリアル通信でそのままモニタに出力しています。

この圧力をサーバーに送信するために、以下のものを買いました。

ArduinoにぶっさすEthernetシールド。ここにLANケーブルをさしてインターネットに接続できます。

PLANEX 300Mbps 超小型ハイパワー無線LANマルチファンクションルータ/アクセスポイント/コンバータ MZK-MF300N

PLANEX 300Mbps 超小型ハイパワー無線LANマルチファンクションルータ/アクセスポイント/コンバータ MZK-MF300N

うちがE-mobilepocket wifiを使っててLANケーブルをさすところがなかったので、有線を無線で使えるようにするコンバータも買いました。

PLANEX 無線LANルータ/アクセスポイント/コンバータ「MZK-MF300N」「FFP-PKR01」専用 USB給電ケーブル SSOP-USB02

PLANEX 無線LANルータ/アクセスポイント/コンバータ「MZK-MF300N」「FFP-PKR01」専用 USB給電ケーブル SSOP-USB02

USBから給電するためのケーブル。

これらをつないでHerokuのサーバーにPOSTリクエストを送ると、node.jsがwebsocketを使ってグラフを更新するようにしました。

コードはこんなかんじ。

上2つのコードを組み合わせると、圧力をPOSTでサーバーに送信できます。で、node.jsで書いたサーバーに送ると以下のような感じになりました。

arduinoのコードとサーバーのコードはともにgithubで公開しています。

https://github.com/naoty/makura-arduino

https://github.com/naoty/makura-web