UbuntuでもRailsがうまく動いてくれない→解決

このあいだ Windows7 64bit で Rails が動いてくれない話を書いた。Ubuntu ではうまくいくかと思ったら話はそう簡単じゃなかった。

このあいだと同じように、書籍を管理するアプリを作ることにする。

takatoh@nightschool:~/w/$ rails new Librarian

本来ならこれだけで Rails サーバを起動できるようになるはず。ところが、

takatoh@nightschool:~/w/$ cd Librarian
takatoh@nightschool:~/w/Librarian$ rails server
/home/takatoh/.rvm/gems/ruby-2.1.1/gems/execjs-2.2.1/lib/execjs/runtimes.rb:51:in autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/execjs-2.2.1/lib/execjs.rb:5:in '
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/execjs-2.2.1/lib/execjs.rb:4:in '
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/uglifier-2.5.1/lib/uglifier.rb:3:in require'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/uglifier-2.5.1/lib/uglifier.rb:3:in '
	from /home/takatoh/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.3/lib/bundler/runtime.rb:76:in require'
	from /home/takatoh/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.3/lib/bundler/runtime.rb:76:in block (2 levels) in require'
	from /home/takatoh/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.3/lib/bundler/runtime.rb:72:in each'
	from /home/takatoh/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.3/lib/bundler/runtime.rb:72:in block in require'
	from /home/takatoh/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.3/lib/bundler/runtime.rb:61:in each'
	from /home/takatoh/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.3/lib/bundler/runtime.rb:61:in require'
	from /home/takatoh/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.3/lib/bundler.rb:132:in require'
	from /home/takatoh/w/Librarian/config/application.rb:7:in '
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:79:in require'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:79:in vblock in server'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:76:in tap'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:76:in server'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:40:in run_command!'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands.rb:17:in '
	from /home/takatoh/w/Librarian/bin/rails:8:in require'
	from /home/takatoh/w/Librarian/bin/rails:8:in '
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/spring-1.1.3/lib/spring/client/rails.rb:27:in load'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/spring-1.1.3/lib/spring/client/rails.rb:27:in call'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/spring-1.1.3/lib/spring/client/command.rb:7:in call'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/spring-1.1.3/lib/spring/client.rb:26:in run'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/spring-1.1.3/bin/spring:48:in '
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/spring-1.1.3/lib/spring/binstub.rb:11:in load'
	from /home/takatoh/.rvm/gems/ruby-2.1.1/gems/spring-1.1.3/lib/spring/binstub.rb:11:in '
	from /home/takatoh/w/Librarian/bin/spring:16:in require'
	from /home/takatoh/w/Librarian/bin/spring:16:in '
	from bin/rails:3:in load'
	from bin/rails:3:in main'

こんな具合にエラーになってしまう。
エラートレースの最初の方に「Could not find a JavaScript runtime.」と書いてある。これが原因らしいので、ググってみるとそのものズバリのページが見つかった。
 cf. rails server 時に `autodetect’: Could not find a JavaScript runtime が出たら。
これによると、therubyracer という gem をインストールするための記述が Gemfile でコメントアウトされているのを、修正してインストールしてやればいいらしい。

gem 'therubyracer', platforms: :ruby

これで bundle install

takatoh@nightschool:~/w/Librarian$ bundle install
(略)

さあ、うまくいくかな?

takatoh@nightschool:~/w/Librarian$ rails server
=> Booting WEBrick
=> Rails 4.1.4 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option)
=> Ctrl-C to shutdown server
[2014-07-06 06:31:57] INFO  WEBrick 1.3.1
[2014-07-06 06:31:57] INFO  ruby 2.1.1 (2014-02-24) [x86_64-linux]
[2014-07-06 06:31:57] INFO  WEBrick::HTTPServer#start: pid=21228 port=3000
rails-welcome-aboard

うまくいった!

Ubuntuの日本語のディレクトリ名を英語にした

Ubuntu のホームディレクトリ以下には、「ドキュメント」とか「デスクトップ」とか日本語の名前がついたディレクトリがある。分かりやすいといえばそのとおりではあるんだけど、cd で移動しようとするといちいち日本語変換しなきゃいけないのが面倒。そこでググってみたら、日本語ディレクトリ名を英語表記に変えられることが分かった。

 cf. Ubuntu 14.04 LTSをインストールした直後に行う設定 & インストールするソフト

このページの手順の通り、コンソールから次のコマンドを打ち込む。

takatoh@nightschool:~$ env LANGUAGE=C LC_MESSAGES=C xdg-user-dirs-gtk-update

するとダイアログが開いて、日本語ディレクトリ名を英語にするかと訊かれるので、Update Names ボタンを押す。
一旦ログアウトして再度ログインすると、今度は英語を日本語にするか、と訊かれるので、「次回から表示しない」にチェックを入れて「古い名前のままにする」ボタンを押す。
これでOK、と思ったら「ピクチャ」と「ダウンロード」だけ日本語のままで残ってる。Pictures と Downloads ディレクトリはあるにも関わらず。仕方がないから手で削除した。

新しいPCが届いたのでWindows7とUbuntuのデュアルブートにした

このあいだ、Ubuntu を VirtualBox にインストールして少し使ってみたけど、なかなかよさ気な感触だったので、新しく買った PC を Windows7 Proffesional と Ubuntu 14.04 LTS のデュアルブートにした。以下、手順のメモ。

PC の起動ドライブの順序を変える

PC の起動中に F2 キーを押して BIOS の画面に移る。で、起動ドライブの順序を内部 HD より CD/DVD が先になるように設定。これで「Ubuntu で始める Linux 入門キット」についていた DVD から起動できるようになった。

パーティションを分割して Ubuntu をインストール

DVD から起動して、インストールを選択する。プリインストールされている Windows7 が検出されてどうするか訊かれるので、Windows とは別にインストールする、を選ぶ。そうするとパーティションを設定する画面になるので、約 200GB を Ubuntu 用に分けた。あとは順番にボタンを押していくだけだ。時間は結構かかるけど、別に難しいところはなかった。まあ、こないだ一回やってるしね。

Ruby と Sublime text 3 と Git をインストール

兎にも角にもこの3つは最初にインストールしなきゃ。Ruby は 2.1.1 を rvm でインストールしたけど、これについてはこのあいだ書いたので省略。あ、ひとつ書いとかなきゃいけないのが、新しく起動したコンソールでは rvm の設定が無効になってるってこと。どうもコンソールの起動時に .bash_profile を読んでいないらしい。bash --login と入力することで有効にできるけど、これは後で調べておかねば。

Sublime text 3 は公式ページから、Ubuntu 64bit 用のバイナリをダウンロードして、インストールした。
 cf. http://www.sublimetext.com/3
Sublime text 自体のインストールは簡単で問題なく終了。あとはパッケージのインストールだけど、↓ここのページが役に立った。
 cf. ubuntu (Xubuntu) 14.04LTS で SublimeText3 の基本(共通)セッティング – けいれん現象の幽玄美よ
とくに Japanize と SublimeMozcInput のインストールのところ。パッケージインストーラで Japanize をインストールし終わるとその後の設定の説明が表示されるんだけど、この説明が Windows 向けの説明なので、ファイルをどこにコピーすればいいのか、このページを見なければわからなかった。
もうひとつ、ひっかかったのが日本語入力。コンソールでは日本語が入力できていたので Sublime Text 3 でも行けるのかと思ったらそうじゃなかった。まずは mozc と emacs-mozc をインストールしなくちゃいけないようだ。上に書いたようにコンソールでは日本語入力ができれるので mozc はインストール済み。で、emacs-mozc は次のようにコンソールからインストールした。

takatoh@nightschool:~$ sudo apt-get install emacs-mozc

その上で次の手順でインストール。

  1. 「ctrl + shift + p」でPackage Controlを開く
  2. 「package」と入力し「Package Control:Add Repository」を選択
  3. 「https://github.com/yasuyuky/SublimeMozcInput」をリポジトリ登録して[Enter]
  4. 「ctrl + shift + p」でPackage Controlを開く
  5. 「install」と入力し「Package Control:Install Package」を選択
  6. 「MozcInput」と入力「SublimeMozcInput」を選択しダウンロード

これでやっと日本語入力ができるようになった!
sublime-japanese

さて、つぎは Git のインストール。これもコンソールから。

takatoh@nightschool:~$ sudo apt-get install git
takatoh@nightschool:~$ sudo apt-get install gitk

そんでもって Windows から SSH のキーを .ssh ディレクトリごと ~/.ssh に持ってきて完了。

DropBox

最後に DropBox についても書いておこう。基本的には↓ここに書いてある通りにやればいい。
 cf. https://www.dropbox.com/ja/install?os=linux
Ubuntu(.deb) 64-bit をダウンロードすればいいようだけど、その下にコマンドラインでのインストール法が書いてあったので、その手順でやった。

takatoh@nightschool:~$ wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -

で、デーモンを起動するらしい。

takatoh@nightschool:~$ ~/.dropbox-dist/dropbox

これでいいのかな。

さて、今日はここまで。

自作のgemをrubygems.orgに公開してみた

新しく作ろうとしているプロジェクトで使うライブラリがあって、しかも2つのプロジェクトで共通に使うつもりなので、こういう場合は gem にしてしまうのがいい。filestorage っていう一般名詞みたいな名前のライブラリだけど gem search してみたら見つからなかったので、いいや、作ってしまえ。
というわけで、ほんとにシンプルなものだけど gem を作って rubygems.org に登録してみた。以下手順のメモ。

Bundlerでプロジェクトを作る

^o^ > bundle gem filestorage
DL is deprecated, please use Fiddle
      create  filestorage/Gemfile
      create  filestorage/Rakefile
      create  filestorage/LICENSE.txt
      create  filestorage/README.md
      create  filestorage/.gitignore
      create  filestorage/filestorage.gemspec
      create  filestorage/lib/filestorage.rb
      create  filestorage/lib/filestorage/version.rb
Initializing git repo in C:/Users/hiro/Documents/tmp/filestorage
warning: LF will be replaced by CRLF in .gitignore.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in Gemfile.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in LICENSE.txt.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in Rakefile.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in filestorage.gemspec.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in lib/filestorage.rb.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in lib/filestorage/version.rb.
The file will have its original line endings in your working directory.

これで gem の雛形ができる。git リポジトリもできていて、ファイルがステージされた状態になっている。まずはここでいったん commit。ライブラリの本体(lib/filestorage/local_filestorage.rb)を書いて、filestorage.gemspec を編集してもう一度 commit。GitHub にリポジトリを作って push しておく。
これでひとまずは出来上がり(まあ、バージョン 0.0.1 だからね)。

rubygems.orgからAPI Keyをとってくる

rubygems.org に gem を登録するには、API Key が必要。サインアップしてあったので(いつやったんだっけ?)、プロファイルの編集ページで API Key を見ることができる。これを %HOME%/.gems/credentials ファイルに保存するんだけど、ワンライナーがページに載っているのでそれを真似して保存した。ただし、載っているのは Unix 向けなので、Windows ではそのまま使えるわけじゃない。とはいってもやってることは簡単で、次のようにすればいい。

^o^ > curl -u takatoh https://rubygems.org/api/v1/api_key.yaml > %HOME%/.gem/credentials

gemをつくって登録する

もう一息だ。まずは gem を作る。

^o^ > bundle exec rake build
DL is deprecated, please use Fiddle
DL is deprecated, please use Fiddle
filestorage 0.0.1 built to pkg/filestorage-0.0.1.gem.

これで pkg ディレクトリの中に filestorage-0.0.1.gem ができた。これを rubygems.org に登録する。

^o^ > bundle exec rake release
DL is deprecated, please use Fiddle
DL is deprecated, please use Fiddle
filestorage 0.0.1 built to pkg/filestorage-0.0.1.gem.
Tagged v0.0.1.
Pushed git commits and tags.
Pushed filestorage 0.0.1 to rubygems.org.

これだけで OK。なんか git のタグをうって GitHub に push までしてくれるみたいだな。

そんでもって、これが登録後のページ。おお、ちゃんと登録されてる!

filestorage

追記

たいしたもんじゃないけど、書いたコードをさらしておく。

# encoding: utf-8

require 'pathname'
require 'fileutils'

module Filestorage

  class LocalFilestorage

    def initialize(base_dir)
      @base_dir = Pathname.new(base_dir)
    end

    def store(path, file)
      fullpath = @base_dir + path
      FileUtils.mkdir_p(fullpath.parent)
      if file.instance_of?(Pathname)
        FileUtils.cp(file, fullpath)
      elsif file.instance_of?(File)
        File.open(fullpath, "wb") do |f|
          f.write(file.read)
        end
      else
        File.open(fullpath, "wb") do |f|
          f.write(file)
        end
      end
      path
    end

    def get(path)
      fullpath = @base_dir + path
      File.open(fullpath, "rb")
    end

  end # of class LocalFilestorage

end # of module LocalFilestorage

なんか、1時間くらい経ってからページをみたら 18 downloads とか書いてある。もう 18 回もダウンロードされたってこと?みんながっかりしただろうな。

さらに追記

参考にしたページを書くのを忘れてた。ここを参考にしました。

 cf. RubyGems.org へ gem を公開する。 – komiyakの通り道

Windows7(64bit)でRailsがうまく動いてくれない

今日は Rails だ。試しに簡単な Web アプリを作ってみるよ。蔵書を管理するアプリにしよう。名前は Librarian だ。
と、意気込んだところだけど、結果から言うをうまくいかなかった。以下その顛末。

まずは Rails のプロジェクトを作る。

^o^ > rails new Librarian

このコマンドでずら~っとファイル一式が生成される。とりあえずはこれで git のリポジトリを作って最初のコミット。

^o^ > cd Librarian

^o^ > git init
Initialized empty Git repository in C:/Users/hiro/Documents/w/Librarian/.git/

^o^ > git add .
warning: LF will be replaced by CRLF in .gitignore.
The file will have its original line endings in your working directory.
(以下略)

^o^ > git commit -m "First commit."
[master (root-commit) 167a985] First commit.
warning: LF will be replaced by CRLF in .gitignore.
The file will have its original line endings in your working directory.
(以下略)

で、次は scaffold。

^o^ > ruby bin/rails generate scaffold book title volume author
DL is deprecated, please use Fiddle
C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/data_source.rb:1
82:in `rescue in create_default_data_source': No source of timezone data could b
e found. (TZInfo::DataSourceNotFound)
Please refer to http://tzinfo.github.io/datasourcenotfound for help resolving th
is error.
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/dat
a_source.rb:179:in `create_default_data_source'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/dat
a_source.rb:40:in `block in get'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/dat
a_source.rb:39:in `synchronize'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/dat
a_source.rb:39:in `get'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone.rb:629:in `data_source'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone.rb:92:in `get'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone_proxy.rb:67:in `real_timezone'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone_proxy.rb:30:in `period_for_utc'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone.rb:549:in `current_period'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/core_ext/object/try.rb:45:in `public_send'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/core_ext/object/try.rb:45:in `try'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/values/time_zone.rb:223:in `utc_offset'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/values/time_zone.rb:396:in `block in []'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/values/time_zone.rb:396:in `tap'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/values/time_zone.rb:396:in `[]'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/core_ext/time/zones.rb:60:in `find_zone!'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/railtie.rb:20:in `block in '
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/in
itializable.rb:30:in `instance_exec'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/in
itializable.rb:30:in `run'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/in
itializable.rb:55:in `block in run_initializers'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:150:in `block in tsort_each'

        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:183:in `block (2 levels) in
each_strongly_connected_component'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:219:in `each_strongly_connec
ted_component_from'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:182:in `block in each_strong
ly_connected_component'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:180:in `each'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:180:in `each_strongly_connec
ted_component'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:148:in `tsort_each'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/in
itializable.rb:54:in `run_initializers'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/ap
plication.rb:288:in `initialize!'
        from C:/Users/hiro/Documents/w/Librarian/config/environment.rb:5:in `'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/ap
plication.rb:264:in `require'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/ap
plication.rb:264:in `require_environment!'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands/commands_tasks.rb:147:in `require_application_and_environment!'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands/commands_tasks.rb:133:in `generate_or_destroy'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands/commands_tasks.rb:51:in `generate'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands/commands_tasks.rb:40:in `run_command!'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands.rb:17:in `'
        from bin/rails:4:in `require'
        from bin/rails:4:in `
'

なんかエラーが出た。どうやら timezone のデータが見つからない、といっているらしい。ついでに(親切にも)http://tzinfo.github.io/datasourcenotfound を見ればいいよ、とも。
早速ページにアクセスしてみる。すると、あった、Gemfile にちょっと記述を追加すればいいらしい。

If you are using a 64-bit version of Ruby on Windows, then add :x64_mingw to the list of platforms as follows:

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]

指示通り、Gemfile に :x64_mingw を追記して、buldle install を実行。

^o^ > ruby bin/bundle install
DL is deprecated, please use Fiddle
Using rake 10.3.2
Using i18n 0.6.9
Using json 1.8.1
Using minitest 5.3.5
Using thread_safe 0.3.4
Using tzinfo 1.2.1
Using activesupport 4.1.1
Using builder 3.2.2
Using erubis 2.7.0
Using actionview 4.1.1
Using rack 1.5.2
Using rack-test 0.6.2
Using actionpack 4.1.1
Using mime-types 1.25.1
Using polyglot 0.3.5
Using treetop 1.4.15
Using mail 2.5.4
Using actionmailer 4.1.1
Using activemodel 4.1.1
Using arel 5.0.1.20140414130214
Using activerecord 4.1.1
Using coffee-script-source 1.7.0
Using execjs 2.2.1
Using coffee-script 2.2.0
Using thor 0.19.1
Using railties 4.1.1
Using coffee-rails 4.0.1
Using hike 1.2.3
Using multi_json 1.10.1
Using jbuilder 2.1.1
Using jquery-rails 3.1.1
Using bundler 1.6.3
Using tilt 1.4.1
Using sprockets 2.11.0
Using sprockets-rails 2.1.3
Using rails 4.1.1
Using rdoc 4.1.1
Using sass 3.2.19
Using sass-rails 4.0.3
Using sdoc 0.4.0
Using sqlite3 1.3.9
Using turbolinks 2.2.2
Using uglifier 2.5.1
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

だけどなんだかちゃんとインストールされたような気配がない。試しにもう一度 scaffold をやってみる。

^o^ > ruby bin/rails generate scaffold book title volume author
DL is deprecated, please use Fiddle
C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/data_source.rb:1
82:in `rescue in create_default_data_source': No source of timezone data could b
e found. (TZInfo::DataSourceNotFound)
Please refer to http://tzinfo.github.io/datasourcenotfound for help resolving th
is error.
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/dat
a_source.rb:179:in `create_default_data_source'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/dat
a_source.rb:40:in `block in get'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/dat
a_source.rb:39:in `synchronize'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/dat
a_source.rb:39:in `get'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone.rb:629:in `data_source'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone.rb:92:in `get'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone_proxy.rb:67:in `real_timezone'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone_proxy.rb:30:in `period_for_utc'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/tim
ezone.rb:549:in `current_period'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/core_ext/object/try.rb:45:in `public_send'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/core_ext/object/try.rb:45:in `try'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/values/time_zone.rb:223:in `utc_offset'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/values/time_zone.rb:396:in `block in []'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/values/time_zone.rb:396:in `tap'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/values/time_zone.rb:396:in `[]'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/core_ext/time/zones.rb:60:in `find_zone!'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/activesupport-4.1.1/lib/act
ive_support/railtie.rb:20:in `block in '
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/in
itializable.rb:30:in `instance_exec'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/in
itializable.rb:30:in `run'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/in
itializable.rb:55:in `block in run_initializers'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:150:in `block in tsort_each'

        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:183:in `block (2 levels) in
each_strongly_connected_component'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:219:in `each_strongly_connec
ted_component_from'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:182:in `block in each_strong
ly_connected_component'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:180:in `each'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:180:in `each_strongly_connec
ted_component'
        from C:/Ruby200-x64/lib/ruby/2.0.0/tsort.rb:148:in `tsort_each'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/in
itializable.rb:54:in `run_initializers'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/ap
plication.rb:288:in `initialize!'
        from C:/Users/hiro/Documents/w/Librarian/config/environment.rb:5:in `'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/ap
plication.rb:264:in `require'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/ap
plication.rb:264:in `require_environment!'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands/commands_tasks.rb:147:in `require_application_and_environment!'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands/commands_tasks.rb:133:in `generate_or_destroy'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands/commands_tasks.rb:51:in `generate'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands/commands_tasks.rb:40:in `run_command!'
        from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/railties-4.1.1/lib/rails/co
mmands.rb:17:in `'
        from bin/rails:4:in `require'
        from bin/rails:4:in `
'

やっぱり同じじゃないか。
仕方がないから、tzinfo-data っていう gem を直接インストールする。

^o^ > gem install tzinfo-data
Fetching: tzinfo-data-1.2014.5.gem (100%)
Successfully installed tzinfo-data-1.2014.5
Parsing documentation for tzinfo-data-1.2014.5
Installing ri documentation for tzinfo-data-1.2014.5
Done installing documentation for tzinfo-data after 3 seconds
1 gem installed

よし、インストールできた。これで大丈夫だろう。

^o^ > ruby bin/rails generate scaffold book title volume author
DL is deprecated, please use Fiddle
C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/tzinfo-1.2.1/lib/tzinfo/data_source.rb:1
82:in `rescue in create_default_data_source': No source of timezone data could b
e found. (TZInfo::DataSourceNotFound)
Please refer to http://tzinfo.github.io/datasourcenotfound for help resolving th
is error.
(以下略)

だめだ~!ちゃんと tzinfo-data はインストールできてるのに何で見つからないんだ。

もしかして Ruby 2.0.0 と Rails 4.1.1 って相性が悪いのか?

追記(2014/07/01)

昨日ダメだった Rails だけど、今日会社の PC (Windows7 32bit、Ruby 2.0.0 32bit)でこっそりやってみたらあっさりとうまくいってしまった。64bit版がダメだってこと?

Ubuntuにさわってみた

昨日、Amazon で見つけて思わずポチった「UbuntuではじめるLinus入門キット」ていう本が届いたので、早速触ってみた。なんか最近 Heroku やったり Node.js やったり忙しいな。今年は Scheme の年じゃなかったのかよ。
本には最新版の LTS(長期サポート版)の 14.04 のディスクがついていて、すぐにでも始められる、と。最初はディスクから起動しようとしたけどダメだった。なんか知らないけど、BIOS の画面に移行するスキも与えずに Windows が起動してしまう。DELL の PC ってこういうもんなの?

それで VirtualBox にインストールしてみることにした(ディスクには VirtualBox 用のイメージが入っている。ついでに VirtualBox もアップデートした)。
VirtualBox マネージャーから新しい VM を作って、途中で「すでにある仮想ハードドライブファイルを使用する」にチェック、本のディスクからコピーして解凍したイメージファイルを指定すれば OK。
VM を起動すると、おお、なんかかっこいい。

あとはとりあえず、Ruby(2.1.1)と Sublime Text をインストールして、挨拶代わりに Ruby スクリプトを書いてみた。

ruby-on-Ubuntu

参考にしたのは以下のページ。
 cf. Rubyプログラミングを始めるための基礎知識とインストール (2/3) – @IT
 cf. ubuntu (Xubuntu) 14.04LTS で SublimeText3 の基本(共通)セッティング – けいれん現象の幽玄美よ

[amazonjs asin=”4798041343″ locale=”JP” title=”Ubuntuではじめる! Linux入門キット 14.04対応”]

追記

Ruby 2.1.1 のインストールについて書いておこう。といっても上の @IT のページの通りにやっただけだけど。
まずは curl のインストール。

takatoh@nightschool:~$ sudo apt-get install curl

つづいて RVM のインストール。

takatoh@nightschool:~$ \curl -sSL https://get.rvm.io | bash -s stable
takatoh@nightschool:~$ source ~/.bash_profile

そんでもって Ruby 2.1.1 のインストール。

takatoh@nightschool:~$ rvm install ruby-2.1.1 --default
takatoh@nightschool:~$ source ~/.bash_profile

これで OK。

Node.jsをさわってみた

この間は Rails をやろう、みたいな事を書いたくせに、ふと気になって JavaScript の本を読んでいる。目的は jQuery なんだけど Node.js が面白そうだったのでさわってみることにした。

まずはダウンロードとインストールから。nodejs.orgにアクセスすると、ページの真ん中に INSTALL ボタンがあるので、クリックしてインストーラをダウンロード。バージョンは v0.10.29。ダウンロードされた node-0.10.29-x64.msi をダブルクリックしてインストールする。特に迷うこともなくインストールは終了。
試しにバージョンを表示してみる。

^o^ > node -v
v0.10.29

うまくインストールできてるようだ。

さて、Node.js には npm というパッケージマネージャが付属している。これでパッケージの管理ができるんだけど、プロジェクトを作るときにも使うらしい。
とりあえずは、単純にリクエストされたファイル(画像)を返すだけのサーバを作ってみることにした。
まずは、プロジェクトのフォルダを作ってその中に移動し、npm init で初期化する。

^o^ > mkdir image_server

^o^ > cd image_server

^o^ > npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install  --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (image_server)
version: (0.0.0) 0.0.1
description:
entry point: (index.js) server.js
test command:
git repository:
keywords:
author: takatoh
license: (ISC)
About to write to C:\Users\hiro\Documents\w\image_server\package.json:

{
  "name": "image_server",
  "version": "0.0.1",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "takatoh",
  "license": "ISC"
}


Is this ok? (yes) yes

いくつか質問に答えると、プロジェクトの雛形が完成。この時点でフォルダの構成はこうなっている。

^o^ > tree /F
フォルダー パスの一覧:  ボリューム OS
ボリューム シリアル番号は FE2A-F7C6 です
C:.
    package.json

サブフォルダーは存在しません

package.json というファイルがあるだけだね。
次は依存するパッケージのインストール。今回はリクエストに応じて送信するファイルの MIME TYPE を調べるために、mime というパッケージを利用する。これを package.json に追加する。

{
    "name": "image_server",
    "version": "0.0.1",
    "description": "",
    "main": "server.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "dependencies": {
        "mime": "*"
    },
    "author": "takatoh",
    "license": "ISC"
}

色をつけたところが追記したところ。"*" は最新のバージョンをインストールすることを示している。ここに特定のバージョンを書けばバージョン指定もできるようだ。
追記が終わったら mime パッケージのインストール。npm install コマンドを使う。

^o^ > npm install
npm WARN package.json [email protected] No description
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No README data
[email protected] node_modules\mime

npm install は package.json を参照して、まだインストールされていないパッケージをインストールしてくれる。パッケージはプロジェクトフォルダの中の node_modules フォルダにインストールされる。この時点でフォルダ構成はこうなっている。

^o^ > tree /F
フォルダー パスの一覧:  ボリューム OS
ボリューム シリアル番号は FE2A-F7C6 です
C:.
│  package.json
│
└─node_modules
    └─mime
        │  LICENSE
        │  mime.js
        │  package.json
        │  README.md
        │  test.js
        │
        └─types
                mime.types
                node.types

node_modules の下に mime がインストールされているのがわかる。

さあ、今度はサーバ本体だ。いろいろ調べながら出来上がったのがこれ。

var http = require("http");
var fs = require("fs");
var url = require("url");
var mime = require("mime");

server = http.createServer(function(request, response) {
  var path = url.parse(request.url).pathname;
  console.log(path);
  var mimetype = mime.lookup(path);
  var filepath = "./images" + path;
  fs.readFile(filepath, function (err, data) {
    if (err) {
      response.writeHead(404, {"Content-Type" : "text/plain"});
      response.write("File not found.");
      response.end();
    } else {
      response.writeHead(200, {"Content-Type" : mimetype});
      response.write(data);
      response.end();
    }
  });
});

console.log("Start server on port 8888.");
server.listen(8888);

require 関数でパッケージを読み込んで変数に代入している。mime 以外は Node.js に付属しているパッケージで、http はその名のとおり HTTP サーバ/クライアント。fs はローカルのファイルシステムにアクセスするため、url はリクエストの URL を解析するために読み込んでいる。
HTTP サーバは、http.createServer で作れる。引数にはリクエストに応答する関数を指定している。この関数には request と response のオブジェクトが引数として渡されるので、request を解析して response に書き込めばいい。今回は、要求されたファイルを ./images 以下から読み込んで送信している。もしエラーが発生したら、404 File not found を返している。
それじゃ、images フォルダにサンプルの画像を配置しよう。

^o^ > tree /F images
フォルダー パスの一覧:  ボリューム OS
ボリューム シリアル番号は FE2A-F7C6 です
C:\USERS\TAKATOH\DOCUMENTS\W\IMAGE_SERVER\IMAGES
│  Penguins.jpg
│
└─data
        Desert.jpg

これで準備は完了。サーバを起動しよう。次のようにする。

^o^ > node server.js
Start server on port 8888.
nodejs-penguins

これでポート 8888 で待ち受けている状態になった。ブラウザからアクセスしてみよう。

うまくいった!

参考にしたページ:
 cf. http://nodejs.jp/nodejs.org_ja/docs/v0.4/api/http.html#request.url
 cf. http://nodejs.jp/nodejs.org_ja/docs/v0.4/api/fs.html#fs.readFile
 cf. http://stackoverflow.com/questions/5316324/automatic-mimetypes-in-javascript-node-js

PythonでRubyのArray#each_sliceみたいなもの

Ruby の配列(Array)には each_slice というメソッドがある。配列のスライスを順に返してくれるイテレータだ。こんなふう。

irb(main):001:0> [0,1,2,3,4,5].each_slice(2){|x| p x}
[0, 1]
[2, 3]
[4, 5]
=> nil

昨日、CodeEval の問題を解くのに、この Array#each_slice が使えると思っていつもの Python じゃなくて Ruby で解いたんだけど、Python には Ruby の Array#each_slice に相当するものがないみたい。

で、今日になってジェネレータを使えばいいんじゃないかと気が付いたので、書いてみた。

def each_slice(lis, n):
    s = 0
    while s < len(lis):
        yield lis[s:s+n]
        s += n

for x in each_slice([0,1,2,3,4,5], 2):
    print x
^o^ >python each_slice.py
[0, 1]
[2, 3]
[4, 5]

上の例では、要素数がちょうど割り切れる数だったけど、半端が出る場合はどうだろう。Ruby だとこうなる。

irb(main):002:0> [0,1,2,3,4,5,6].each_slice(2){|x| p x}
[0, 1]
[2, 3]
[4, 5]
[6]
=> nil

Python で書いたスクリプトだと:

^o^ > python each_slice.py
[0, 1]
[2, 3]
[4, 5]
[6]

IndexError になるかと思ったけど、期待通りに動いた。

HerokuとRailsの本を読んだ

こないだ Heroku を使ってみて成功したので、今度は Rails でやってみようかと、「HerokuではじめるRailsプログラミング入門」という本を読んだ。
「Herokuではじめる」とは書いてあるけど、Heroku についてはほんのちょっとしか書いてなくて、基本的に Ruby on Rails の入門書。それも Rails3 準拠のようで、最新の Rails を使うにはもうちょっと足りない、という感じ。
とはいえ、Rails は何年も前(たしかバージョンが 2.0.2 だったかな)に使ったきりほとんど忘れていたので、どんな感じかを思い出すのにはちょうどよかった。
もう少し Rails4 の本を読んで、この2年ほど動いていない Rails アプリを作り直そう。

Amazon S3にファイルをバックアップする

先週、Amazon S3 が使えるようになったので、ファイルのバックアップに使ってみることにした。環境は Windows7。
もともと、バッチファイルで外付け HDD にバックアップをとっていたから、S3 にも同じようにできないかと探してみたら、DragonDisk に付属している dgsync というのがいいらしい、ということがわかった。参考にしたページはここ。

 cf. WindowsコマンドでAmazon S3上にバックアップする – Hack Your Design!

DragonDisk はここからダウンロードできる。

 cf. http://www.dragondisk.com/download-amazon-s3-client-google-cloud-storage-client.html

なんかパッケージの写真が載ってて有料のソフトみたいに見えるけど、無料らしい。ここから DragonDisk v1.05 for Windows をダウンロードした。
インストールは簡単で、特に書くほどのことはない。

で、バックアップ用のバッチファイルだけど、上の参考にしたサイトに載っているのでほぼそのまま使わせてもらった。

SET DGTOOLS_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXX
SET DGTOOLS_SECRET_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

"C:\Program Files (x86)\Almageste\DragonDisk\dgsync" -v --ssl --dont-delete --endpoint "s3-ap-northeast-1.amazonaws.com" "T:\backup\takatoh" "s3://panicblanket/backup/valarie/takatoh"

バックアップ元で削除したファイルを S3 からも削除するには –dont-delete オプションをはずす。

さて、これを実行してバックアップをとったわけだけど、スゲー時間がかかったよ。寝てる間にバックアップするのがいいかもね。