follow us in feedly

Ruby

Rubyのinjectで配列の各要素の合計を計算する

Rubyのinjectで配列の各要素の合計を計算する方法のメモ。

Rubyで配列の合計を計算したいとなったんだけど、
ふと、いつもと違うやり方はないかな、ちょっとでも簡単に書きたいなと思って、
Rubyなら何か方法があるんじゃないのと調べてみました。

そしたら、ありました。
Enumerable#injectで配列の合計がちょっとだけスッキリ書けます。

injectで配列の値の合計を計算する

配列の合計を計算する場合は、たいていこんな感じになります。
下記は1から10までの値を合計しています。

sum = 0
(1..10).each { |i| sum += i }
p sum # 55

上記をinjectを使って書くとこうなります。
injectに渡す引数は、sumの初期値になります。つまり、sum = 0です。
引数を省略したときは、先頭の要素をsumに代入して、2番目の要素からループが開始します。
また、injectは返り値としてsumの値を返します。

(1..10).inject(0) { |sum, i| sum + i } # 55

# 引数を省略
# sum = 1として、sum + 2からループ開始
(1..10).inject { |sum, i| sum + i } # 55

ということで、injectで配列の合計の計算がちょっとだけスッキリ書けました。

injectは、引数に渡すオブジェクトの種類によって使い道がいろいろあるようですが
そのあたりはもうちょっと勉強して使ってみないとよくわかんないな。

Rubyのハッシュ作成時にデフォルト値を指定する方法が便利

Rubyでハッシュの値にハッシュや配列を持たせたい場合の便利な方法をメモ。
ハッシュの値としてハッシュを入れる場合は毎回初期化してあげないとエラーになりますが、
ハッシュの作成時にキーに対応する値が未定義の場合のデフォルト値を指定すると上手くできます。

ブロックを使ってハッシュにデフォルト値を指定する

下記のようにh[‘foo’][‘bar’]に値を代入しようとしてもエラーになります。
h[‘foo’]はnilなので、[]=メソッドがないと怒られます。

h = Hash.new
h['foo']['bar'] = 100 # NoMethodError: undefined method `[]=' for nil:NilClass

今まではエラーにならないように毎回初期化してたんだけど。

h = Hash.new
h['foo'] = Hash.new
hash['foo']['bar'] = 100
p hash # {"foo"=>{"bar"=>100}}

下記の1行目のようにすると、h[‘foo’]が未定義の場合に自動でデフォルト値を代入してくれる。
この場合は、{}(ハッシュ)が代入される。

h = Hash.new { |hash, key| hash[key] = Hash.new }
hash['foo']['bar'] = 100
p h # {"foo"=>{"bar"=>100}}

# 値があればデフォルト値は代入されない
h['hoge'] = 200
p h # {"foo"=>{"bar"=>100}, "hoge"=>200}

なかなか便利でいい感じです。
ソースコードがちょっとすっきりしました。

rake db:createコマンドのデータベース作成時の動作について

前回の記事では下記の手順でデータベースを作成していました。
1. MySQLでユーザを作成
2. config/database.ymlに設定を記述
3. rake db:createコマンドを実行

ですが、ユーザを作成していなくてもrakeコマンドはデータベースを作成します。
ユーザが存在しない場合、rakeコマンドはデータベース作成時にユーザも作成するわけです。

ためしにやってみます。
前回の「MySQLユーザの作成」をとばして、config/database.ymlに設定を追加します。

development:
  …
  username: testuser
  password: testpass
  …
test:
  …
  username: testuser
  password: testpass
  …

rake db:createコマンドを実行すると、下記のようにMySQLのrootパスワードを聞いてきます。

$ rake db:create
Access denied for user 'testuser'@'localhost' (using password: YES).
Please provide the root password for your mysql installation
>

MySQLのrootパスワードを入力するとデータベースが作成されます。
このときにユーザを作成して、データベースへの権限も付けています。

データベース作成時のクエリを出してみました。
WITH GRANT OPTIONは他のユーザに自分と同じ権限を与えられるみたいです。
ここでは、rails_app_development のすべての権限かな。

CREATE DATABASE `rails_app_development` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
GRANT ALL PRIVILEGES ON rails_app_development.* TO 'testuser'@'localhost' IDENTIFIED BY 'testpass' WITH GRANT OPTION

ただし、MySQLのユーザが存在していてもrootパスワードを聞かれることがあります。
config/database.ymlに記述したパスワードが間違っている場合です。
この場合もrootパスワードを入力するとデータベースが作成されますが、このときにMySQLのユーザのパスワードが間違ったものに書き換わってしまうので注意してください。

意図せずrootパスワードを聞かれた場合は、中断(Ctrl-C)して設定を確認したほうがよさそうです。

Rails 3.2とMySQLでアプリケーションを作成する

前回の記事(1ヶ月以上も前…)で Rails 3.2 の開発環境を構築しました。
ここから、少しずつでもいいのでアプリケーションを作っていきたいですね。
とりあえず、Rails と MySQL でアプリケーションの基礎構築までやってみました。
途中までは前回と同じような内容です。

サーバ環境や Rails 環境の構築は下記あたりを参考にしてください。
さくらVPS に nginx + WordPress の環境を構築する(1) – SSH の設定 | 77 Dogs Blog
さくらVPSに Rails 3.2 の開発環境を構築する | 77 Dogs Blog

Rails アプリを作成する

Rails アプリを作成して、アプリのディレクトリに移動します。
MySQLを使うためのオプションをつけて作成します
–skip-bundle オプションをつけると「bundle install」が実行されなくなります。

$ rails new rails_app -d mysql --skip-bundle
$ cd rails_app

作成されたディレクトリに移動して、Gemfile に下記を追加します。
下記を追加しないと Rails コンソールの起動やデータベース作成時に Javascript ランタイムエラーが出ます。

gem 'execjs'
gem 'therubyracer'

bundle install を実行して gem をインストールします。
-–path オプションでインストール先を指定できます。パスの指定は初回だけで大丈夫です。

$ bundle install --path vender/bundle

MySQL ユーザを作成する

MySQL のユーザを作成し、データベースを操作するための権限を設定します。

$ mysql -u root -p
Enter password:

mysql> CREATE USER 'testuser'@'localhot' IDENTIFIED BY 'testpass';
mysql> GRANT ALL ON rails_app_development.* TO 'testuser'@'localhost';
mysql> GRANT ALL ON rails_app_test.* TO 'testuser'@'localhost';

データベースを作成する

アプリで使用するデータベースを作成します。
まずは、config/database.yml に下記を追加します。

development:
  …
  username: testuser
  password: testpass
  …
test:
  …
  username: testuser
  password: testpass
  …

下記コマンドを実行して、データベースを作成します。
config/database.yml に定義した development と test のデータベースが作成されます。

$ rake db:create

以上で、Rails と MySQL を使ったアプリケーションが作成できました。

補足1: production のデータベースを作成する

production のデータベースを作成する場合は、config/database.yml の production: 以下を編集します。

production:
  …
  username: testuser
  password: testpass
  …

RAILS_ENV=production オプションをつけて、コマンドを実行します。
production のデータベースのみ作成されます。

$ rake db:create RAILS_ENV=production

また、 下記コマンドを実行すると config/database.yml で設定したデータベースがすべて作成されます。

$ rake db:create:all

補足2: データベースを削除する

データベースを削除するには、下記コマンドを実行します。
オプションや all の意味は、rake db:create と同じです。

$ rake db:drop
$ rake db:drop RAILS_ENV=production
$ rake db:drop:all

さくらVPSにRails 3.2の開発環境を構築する

さくらVPSに Rails 3.2 の開発環境を構築しました。
Ruby のバージョン管理に rbenv を利用して構築します。
ちょこちょことエラーがでて、思ったより時間がかかりました。
Ruby のバージョンは 1.9.3 です。

rbenv をインストールする

Ruby のバージョン管理ツールとして rbenv をインストールします。
下記を参考に複数のユーザアカウントで利用できるように設定します。
shared install of rbenv

まずは、rbenv 用にグループを作成してユーザを所属させます。

# groupadd (グループ名)
# usermod -G (グループ名) (ユーザ名)

rbenv と ruby-build をインストールします。

# cd /usr/local
# git clone git://github.com/sstephenson/rbenv.git rbenv
# chgrp -R (グループ名) rbenv
# chmod -R g+rwxXs rbenv
# mkdir /usr/local/rbenv/plugins
# cd /usr/local/rbenv/plugins
# git clone git://github.com/sstephenson/ruby-build.git
# chgrp -R (グループ名) ruby-build
# chmod -R g+rwxs ruby-build

インストールが完了したら、環境変数を設定します。
各ユーザごとに ~/.profile や ~/.bash_profile あたりに下記を追加します。
他にも設定方法があるようですが自分用なのでこれで。

export RBENV_ROOT=/usr/local/rbenv
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"

Ruby をインストールする

rbenv を使って Ruby をインストールします。

$ rbenv install ← Ruby のバージョン一覧が出る
$ rbenv install 1.9.3-p194
$ rbenv rehash
$ rbenv global 1.9.3-p194

設定したユーザで Ruby のバージョンが確認できれば大丈夫です。

$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]

Rails をインストールする

gem を使って Rails をインストールします。
gem コマンドを実行するときに下記のエラーが出るので、まずは zlib-devel をインストールします。インストール済みなら問題ないです。

ERROR:  Loading command: install (LoadError)
    cannot load such file -- zlib
ERROR:  While executing gem ... (NameError)
    uninitialized constant Gem::Commands::InstallCommand

さらに、下記のエラーも発生するので openssl-devel もインストールします。
これも、インストール済みなら問題ないです。

/root/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- openssl (LoadError)

zlib-devel と openssl-devel をインストールします。

$ sudo yum install zlib-devel
$ sudo yum install openssl-devel

Rails をインストールします。
インストール時に “file ‘lib’ not found” とエラーが出るので下記のオプションを付けるか、先に rdoc をインストールすれば解決です。

$ gem install rails --no-ri --no-rdoc

Rails アプリを作成する

Rails アプリの作成をします。
ここでも、mysql-devel がないとエラーが出るのでインストールをします。

$ sudo yum install mysql-devel

Rails アプリを作成して、アプリのディレクトリに移動します。
MySQL を使うのでオプションをつけて作成します。

$ rails new rails_app -d mysql
$ cd rails_app

Bundler で gem をインストールします。
–path オプションでインストール先を指定できます。パスの指定は初回だけで大丈夫です。

$ bundle install --path vendor/bundle

Rails コンソールの起動などをしようとすると下記の Javascript のランタイムエラーが出ます。

Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes.

エラーが出た場合は、Gemfile に下記を追加して execjs と therubyracer をインストールします。

gem 'execjs'
gem 'therubyracer'

bundle コマンドを実行してインストールします。

$ bundle install

これで、Rails の開発環境が構築できました。

HomebrewでRuby 1.9.3をインストールする

新しい職場では Ruby を使うことになりそうなので、勉強のために Ruby をインストールしました。
Mac にはデフォルトで Ruby が入っているようですが、バージョンが 1.8 と古いものなので最新版の Ruby をインストールします。

Homebrew で Ruby をインストールする

Homebrew で Ruby 1.9.3 をインストールします。
まずは、Ruby のバージョン管理ツールの rbenv と readline をインストールします。

$ brew install rbenv
$ brew install ruby-build
$ brew install readline
$ brew link readline

.bash_profile や .bashrc あたりに下記を追加します。

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

Ruby をインストールします。
rbenv install とするとインストールできる候補の一覧が表示されます。

$ rbenv install
$ CONFIGURE_OPTS="--with-readline-dir=/usr/local" rbenv install 1.9.3-p125
$ rbenv rehash
$ rbenv global 1.9.3-p125
$ ruby -v
ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-darwin11.3.0]

Ruby をインストールするところで GCC がないと下記のようなエラーが出るので、その場合は kennethreitz/osx-gcc-installer から GCC をダウンロードしてインストールします。
Homebrew で GCC をインストールする場合はこちら

$ rbenv install 1.9.3-p125

ERROR: This package must be compiled with GCC, and we
couldn't find a suitable `gcc' binary on your system.
Please install GCC and try again.

As of version 4.2, Xcode is LLVM-only and no longer
includes GCC. You can install GCC with these binary
packages on Mac OS X:

https://github.com/kennethreitz/osx-gcc-installer/downloads

BUILD FAILED

以上で完了です。