Rake入門

taskの依存関係を理解する

最初のサンプルなので、順を追って説明していきます。

①単純なtask

task :default => :daily_report

desc "1日のトレーニング内容を記録する"
task :daily_report do
  puts "レポートを作成しました。"
end

task :default => :daily_reportにより、rakeコマンドを簡潔に実行できる。

$ rake
#=> レポートを作成しました。

・descに記述したものは以下のコマンドで見ることが出来る。

$ rake -T
#=> rake daily_report  # 1日のトレーニング内容を記録する

②依存関係を記述する

task :default => :daily_report

desc "1日のトレーニング内容を記録する"
task :daily_report => [:run,:swim] do
  puts "レポートを作成しました。"
end

desc "1日のswim量を報告します"
task :swim do
  puts "今日あなたは2キロ泳ぎました"
end

desc "1日のrun量を報告します"
task :run do
  puts "今日はあなたは4キロ走りました"
end

task :daily_report => [:run,:swim] doの部分でtaskdaily_reportの依存関係を記述できます。

$ rake
#=> 今日はあなたは4キロ走りました
#=> 今日あなたは2キロ泳ぎました
#=> レポートを作成しました。

task :daily_report => [:swim,:run] doとすると実行順序が変わることがわかります。

$ rake
#=> 今日あなたは2キロ泳ぎました
#=> 今日はあなたは4キロ走りました
#=> レポートを作成しました。

・依存関係をクリアしないとrakeは失敗します。 以下のようにdaily_reportの依存関係の1つであるswimをコメントアウトしてrakeを実行します。

task :default => :daily_report

desc "1日のトレーニング内容を記録する"
task :daily_report => [:swim,:run] do
  puts "レポートを作成しました。"
end

#desc "1日のswim量を報告します"
#task :swim do
#  puts "今日あなたは2キロ泳ぎました"
#end

desc "1日のrun量を報告します"
task :run do
  puts "今日はあなたは4キロ走りました"
end
$ rake
#=> rake aborted!
#=> Don't know how to build task 'swim' (see --tasks)

ファイルタスク:差分ビルドの実現

Rake

タスクではなく、あえてファイルタスクを用いる理由、それは差分ビルドの実現にある。 タスクとして定義された場合、そのタスクは必ず実行される。もっと言えば、いまそれをする必要が無くとも、定義されている以上実施してしまう。しかし、ファイルタスクの場合、必要なときだけタスクを実施するのである。具体的には、定義されたファイルを作ろうとする際、まず目的ファイルが作成済みかどうかを調べる。作成済みであれば、続けて依存先のファイルの更新日時を調べ、それが目的ファイルよりも新しくなっている場合のみ、変更があったと見なしてビルド作業を実施するのだ。これは大変な時間の節約になる。

例えば、同一フォルダ内に以下のようなファイルが3つある場合を想定します。

$ ls
#=> Rakefile  report.txt  run.txt  swim.txt
$ cat run.txt
#=> run: 12キロ
$ cat swim.txt
#=> swim: 5キロ
$ cat report.txt
#=> swim: 5キロ
#=> run: 12キロ
task :default => :report

desc "ファイルに記録します"
task :report => "report.txt"
file "report.txt" => ["swim.txt","run.txt"] do
  puts "ファイルを記録します"
  swim = File.read("swim.txt")
  run = File.read("run.txt")
  report = swim + run
  File.open("report.txt","w") do |file|
    file.puts(report)
  end
end

ポイントはfile "report.txt" => ["swim.txt","run.txt"] doで、report.txtswim.txtrun.txtに依存していることです。 このような関係にある時、swim.txtrun.txtに変更が加わらなければ、file'report.txt'が更新されることはありません。

$ rake

なにも実行されません。

$ echo "swim: 20キロ" > swim.txt
$ rake
#=>  ファイルを記録します

今度はfile'report.txt'が更新されていることがわかります。

$ cat report.txt
#=> swim: 20キロ
#=> run: 12キロ

C言語コンパイル

基本的なことだけ

CC = "gcc"

task :default => "hello"

file "hello" => ["hello.o"] do
    sh "#{CC} -o hello hello.o"
end

file "hello.o" => "hello.c" do
    sh "#{CC} -c hello.c"
end

task :clean do
    sh "rm -rf hello *.o"
end

・依存関係を辿って行くと、hello=>hello.o=>hello.c

gcc -c hello.c hello.oが作成される コンパイルのみ行う(オブジェクトファイルを生成する).

gcc -o hello hello.o hello.oをhelloにリンクする

・コマンドを実行するときは、

$./hello

・rakeを2度実行しても何も起こらない

・hello.cを変更すれば、gcc -c hello.cgcc -o hello hello.oの両方が実行される。

・hello.oを変更すればgcc -o hello hello.oだけ実行される。

f:id:taiki44no:20171101215944p:plain

参照

rake 公式 C言語のビルドでほのぼのrakeでmakeするよ るびくる&RBのRubyプログラミング大作戦! ファイルを扱う作業をRakeで便利にしよう!(パート1:概要編) パーフェクト Ruby [Ruby][rake]Rakefileでgccコンパイルしてみる コンパイラ(gccコマンド)の使い方

Ruby Style Guideを読んでの気づきリスト

はじめに

Ruby Style Guide読んだ。

普段、自分がrubyを使っている時には意識できていなかった点をピックアップしていきます。

case文にインデントはいらない

case
when song.name == "Misty"
  puts "Not again!"
when song.duration > 120
  puts "Too long!"
when Time.now.hour > 21
  puts "It's too late"
else
  song.play
end

stringの配列には%wを使おう(パーセント記法)

STATES = %w(draft open closed)

why???

[初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか

文字列だけの配列を作りたい場合は%w( )を使うと少し短く書けます。

Stringに関していろいろ

・文字列の場合は結合を使わない

email_with_name = "#{user.name} <#{user.email}>"

・<< のほうが速い

html = ""
html << "<h1>Page title</h1>"

コーディング規約をまとめてみた (Ruby編)

String#+ は非破壊的なメソッドであるため。String#+ は文字列結合するたびに新しい文字列を生成する。 そのため、String#<< のほうが速い。

Forはあんま使うな。each使おう

大抵の場合、forはeachで代替できる。

・for 式で使用する変数 (上の例でいう elem) が for 式の外からでも呼び出せてしまうため

・each メソッドで使用する変数はブロックスコープ内で宣言されるため、ブロックの内側からでしか呼び出せないため

if とか条件分岐周り

・thenは使わない

・if/then/else/end が1行で書けるような処理の場合は、代わりに三項演算子を使用する。 ※ただし、ネストしたり複雑なときはif/elseを使う(読みやすさが大事)

result = some_condition ? something : something_else

・and や or は使わない。&& や || を使おう

・unless と elseは併用しない(常にifとelseで書き換え可能なので)

・ifの条件を()で囲わない

block

・シングルラインだったら{}で囲い、マルチなら囲わない。

arr.each { |elem| puts elem }
names.select { |name| name.start_with?("S") }.map { |name| name.upcase }

式の定義

デフォルトの値を入れるときはスペースを入れる

# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end

クラス

・継承に関連して変わった挙動をすることがあるので、クラス変数@@は使わないこと。 (インスタンス変数はOK)

→継承先でもクラス変数の値が残るから。

・public、protectedやprivateは、メソッド定義と同じインデントの深さにすること。また、それぞれの上には空行を入れること。

rbenvをアップデートして最新のruby(2.4.2)を入れる

方法

rbenvは既にインストール済みであることが前提です。

① rbenv-updateをインストール

rbenv-updateを使ってRubyのバージョンを上げたついでにRailsをインストールした(CentOS)

gem: rkh/rbenv-update

$ git clone https://github.com/rkh/rbenv-update.git "$RBENV_ROOT/plugins/rbenv-update"

以上。

rubyをインストールする

rbenvのパスを通しているディレクトリ直下にpluginsというディレクトリを作る必要がありますが、通常既にruby-buildなどを入れる時に作成しているはずです(たぶん)。

$ rbenv update
$ rbenv install -l
$ rbenv install 2.4.2
$ rbenv global 2.4.2

実行

$ rbenv versions

f:id:taiki44no:20171030071620p:plain

$ rbenv global 2.3.1 
$ ruby -v

f:id:taiki44no:20171030071624p:plain

kulku: ローカル環境立ち上げ

前提

・deboian(virtualbox + vagrant)

・rbenv

GitHubのためにSSHキーの設定を行う

RubyRailsのバージョンを合わせる

Ruby: 2.4 Rails: 5.1.4

すでに、rubyrailsが入っている場合は、

1:Railsを消す

2:Rubyをインストール後切り替える

3:Railsをインストール

bundle

pg関連のエラー

apt-get install postgresql libpq-dev

pgのインストール中にエラーが出た

rake db:setup

uglifiter関連のエラー

Gemfileに以下を追加

gem 'therubyracer', platforms: :ruby

vagrantユーザがいないとpostgresに怒られる

$ sudo su - postgres
psql
create user vagrant createdb password 'vagrant' login;
\du
\q

33歳からのWEBサービス・スタートアップ

rails sの後のエラー

Cannot render console from 10.0.2.2!

config/application.rb

config.web_console.whitelisted_ips = '10.0.2.2'

PostgreSQL: PG::NotNullViolation: ERROR

ユーザ登録する時に上手く行かなかった。

tapsでMySQLからPostgreSQLに移行した後に起きたトラブル事例

null制約があるところは、default値を指定してあげればよいらしい。

db/schema.rb

こんな感じ(userテーブルでnull:false制約があるところは全部)。

t.string "name", default: "", null: false

schemaの設定を読み込み反映させる

$ rake db:schema:load

Railsのdb/schema.rbの役割

Deviseのメールが届かない(ユーザー登録がうまくできない)

ログを見ると上手く言っているように見えるけどどうしても届かない。

ちなみに、デフォルトの状態だとメール関連のエラーが吐かれないようになっているのでそこも修正してはみた。

ActionMailerでメールが送信されないない人はここを見直そう

config/environments/development.rb

config.action_mailer.raise_delivery_errors = true

でも、相変わらずエラーは無かった。

結局、letter_opener_web(最初から入っているgem)を使って認証させた。 (letter_opener_webを使うと実際のアドレスにはメールはいかないのか?ちょっとわからなかった。)

http://localhost:3000/letter_opener

にアクセスして、右側で認証すればオッケー。

http://k-shogo.github.io/article/2013/11/06/rails-letter-opener/

開発中にrailsから送信したメールを確認する

kowabana :ローカル環境作成時:エラー対処集

はじめに

ローカル環境:vagrant + virtualbox仮想マシン(Debian8)

リモートリポジトリをローカル環境で立ち上げようと思った時、いろいろエラーが起きました。

エラーに関する、自分なりの対処法です。

cloneする時:fatal: could not create work tree`

fatal: could not create work tree dir 'kivy'

ディレクトリを作成し、その中でcloneを実行して下さい。 アクセスの権限を変えることでも可能だと思います。

$ mkdir my_git
$ cd my_git
$ git clone git@github.com:_git_name_.git

bundle:”An error occurred while installing mysql2”が起きたら

エラーメッセージに従い、以下で解決しました。

$ sudo apt-get install libmysqlclient-dev
$ bundle

rails サーバー起動する時:  There was an error while trying to load the gem 'uglifier'. (Bundler::GemRequireError)

Gemfileに追記

gem 'therubyracer', platforms: :ruby

Rake aborted, Error while trying to load the gem 'uglifier'

$ sudo apt-get install nodejs

でも解決するならこちらが良いかも(Gemfileを汚さない)。

※nodejsをインストールすると、'uglifier'のエラーは回避できますが、railsサーバー起動時に、ExecJS::RuntimeErrorが出てしまったので、結局、therubyracerの方向で行きました。

rails サーバーを起動する時: Could not open library 'libcurl'

$ sudo apt-get install libcurl3

Could not open library 'libcurl': libcurl: cannot open shared object file: No such file or directory

rails s しても何も表示されない

ターミナル上は起動しているように見えるけど、対象のアドレスにアクセスできない。

$ rails s -b 0.0.0.0

rails sで起動したサーバにブラウザからアクセスできない

mysql: Access denied for user 'root'@'localhost' (using password: NO)

railsのapp作成でmysqlを使用する時の導入とハマるところ rake db:createができるまでの流れ

config/database.ymlにあるファイルにあるパスワードの欄が空白なので自分で値を入れて設定する。

Mysql2::Error: Specified key was too long; max key length is 767 bytes

Rails(ActiveRecord)とMySQLでutf8mb4を扱う設定

ActiveRecordのstring型カラムがvarchar(255)で定義されるので、utf8mb4ではインデックスのキープレフィックスが767byteを超えてしまう。

Railsの設定に関して、

MySQL5.7.9以上を利用しているならdatabase.ymlにおいてutf8mb4を設定すればよく、とくべつなことをする必要はない。

ようなので、MySQLを最新のものに入れます。 (my.cnfへの追記などもしたけど、上手くいかなかった。)

Ubuntu14.04 に mysql 5.6 を再インストールした

mysql-serverの削除

$ sudo apt-get remove --purge mysql-server* mysql-common
$ sudo apt-get autoremove --purge

②APTリポジトリ設定用のパッケージ取得(2017/10月では以下が最新) https://dev.mysql.com/downloads/repo/apt/

$ wget http://dev.mysql.com/get/mysql-apt-config_0.8.8-1_all.deb
$ sudo dpkg -i mysql-apt-config_0.8.8-1_all.deb

リポジトリの更新後、インストール

$ sudo apt-get update
$ sudo apt-get install mysql-server
$ mysql-server --version

現時点では、5.7.19がはいる。

アップグレードするとlibmysqlclient_r.so.16: cannot open shared object file: No such file or directoryみたいなエラーがでるかもしれない。

CentOs 6.4(sakura vps)でMySQLのバージョンを5.6にする

mysql 5.6にアップデートすると、libmysqlclient_r.so.16がlibmysqlclient_r.so.18に変わっていました。

$ gem uninstall mysql2
$ gem install mysql2

で解決する。

Rails サーバー起動時に、自動的にkilledされてサーバーが落ちてしまう。

Why does my WEBrick server get killed?

It runs out of memory. The linux kernel kills it. Droplets don't come with any 'swap' by default, so when the memory gets full, it kills a process or won't let you start a new one. Kinda crazy.

超訳linux kernel はメモリー不足が起きるとkillしちまうのさ!

そうです。 vagrantの設定が問題です。

Vagrant で Virtualbox 仮想マシンのメモリ割り当てを増加させる

$ free -m

このコマンドでわかりますが、vagrantではデフォルトのでは480MBが仮想マシンに振り分けられています。

なので、これを拡張します。

ローカル環境に移動して、Vagrantfileをいじります(以下では参照に従い、1GB 割り当てます)。

コメントアウトしてあった部分を有効化しただけです。

config.vm.provider "virtualbox" do |vb|
      vb.memory = "1024"
end

vagrantをリロードして仮想マシンに入ります。

$ vagant reload
$ vagrant ssh

メモリが拡張されていることがわかります。

$ free -m

killedの問題も解決しました。

GitHubへssh接続する

はじめに

参照:Connecting to GitHub with SSH

GitHubへのリモートリポジトリからcloneする時は、ssh keyが必要に成ります。

SSH keys があるかを確認します。

$ ls -al ~/.ssh

この時、下のいずれかが存在すればSSH keysは存在しますが、自分の場合は無かったので新規に作成します。

id_dsa.pub
id_ecdsa.pub
id_ed25519.pub
id_rsa.pub

ssh key を生成します

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

GitHubで登録しているメールアドレスでOK。

Enterを押すといろいろ聞かれます。

・Enter a file in which to save the key (/home/you/.ssh/id_rsa): =>デフォルトの場所にファイル生成してOKなのでEnter!

・Enter passphrase (empty for no passphrase): =>パスワードを適当に入力(接続する時必要なので覚えておく必要はある)

・Enter same passphrase again: =>パスワードの確認

~/.ssh/id_rsaid_rsa.pubが生成されていることがわかります。

③作成したssh keysをGithubに登録する

id_rsa.pubをコピーして、 Personal settings > SSH and GPG keys > New SSH Keyボタン

titleは適当(jassie とか)に、Keyにコピーしたのをペースト。

そして、Add SSH keyボタン。

Debian8にrbenvでRubyとRailsを導入する

環境

以下の環境で行いました。

vagrant

virtualbox

・box-url: https://app.vagrantup.com/debian/boxes/jessie64

Ruby with rbenv

①apt-getをアップデートする

$ sudo apt-get update

②rbenvに必要なものをインストール

$ sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev

③gitもインストール

debian8では、rbenvをgitからcloneします。

$ sudo apt-get install git 

※git-coreはいりません パッケージ: git-core (1:2.15.0~rc0-1)

'git-core' パッケージは 'git' に 改名され、新しいパッケージは自動的にインストールされます。この git-core パッケージは現在は廃止予定で、他のパッケージがこれに依存していなければ システムから安全に削除できます。

④rbenvをクローン

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv

⑤rbenvにPATHを通す

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc

⑥設定の読み込み

$ source ~/.bashrc
$ rbenv -v

ruby-buildをクローンする

rbenvにinstallコマンドを使えるようにするには、ruby-buildが必要です。

$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

Rubyをインストールする

rbenv install -l

でインストールできるRubyのバージョンが表示されます。 今回は、バージョンを2.4.2で指定します。

$ rbenv install 2.4.2

ruby 2.4.2の新しい機能はこちらを参照させていただいてワクワクしましょう。 サンプルコードでわかる!Ruby 2.4の新機能と変更点

⑨rbenvを更新する

rbenvを更新します。

$ rbenv rehash

使用するrubyのバージョンをインストールした2.4.2にします。

$ rbenv global 2.4.2
$ ruby -v

例えば、rubyのバージョンを変更したい場合も簡単に行うことができます。

(ⅰ)rbenv install 2.3.0

(ⅱ)rbenv rehash

(ⅲ)rbenv global 2.3.0

Rails with Gem

①bundlerをインストールする

--no-document をつけないとRDocドキュメントというものが生成されてしまって遅いらしいです。以下のように書き込んでおいて、毎回、--no-documentをするのを避ける作戦。

$ echo "gem: --no-document" > ~/.gemrc

bundlerをインストールする

$ gem install bundler

Railsをインストールする

最新版を入れたければ以下のようにします。

$ gem install rails

バージョンを指定したければ以下のようにします

$ gem install rails -v 4.2.7

③rbenvの更新

$ rbenv rehash
$ rails -v

Railsのバージョンの切り替え

3分でできるRailsダウングレード

$ rails -v
$ gem uninstall rails 
$ gem uninstall railties -v '4.2.1'
$ rails -v
$ gem install rails -v '4.2.0' --no-rdoc --no-ri 
$ rails -v

rubyrailsは関係性が強いので、rubyのバージョンも切り替えたい場合は、railsを消す=>rubyのバージョンを切り替える=>railsを新規に作成する、の順番で行います。

MySQL

MySQLをインストールする

$ sudo apt-get update
$ sudo apt-get install mysql-server
$ mysql --version

MySQL5.5.57が入ります(2017/10月時点)。

より新しいものをインストールしたい場合は、こちらを参照させてもらいます。 (個人的には最新版をおすすめ)

Debian 8 に MySQL 5.7.11をインストール

Mysql特有の操作はこちらを参照 MySQLコマンドまとめ

Vimのインストール

Vim の設定

①普通にインストール

$ sudo apt-get install vim

エイリアス /etc/profile

alias vi='vim'

③設定読み込み

source /etc/profile 

Boxとして保存する方法

再利用するためにboxを保存しましょう。 ローカル環境に戻って作業します。

①パッケージ化

$ vagrant package

package.boxが作成されます。

②Virtual Boxに登録

$ vagrant box add box_name package.box
$ vagrant box list

これで完了。

※再利用する場合

$ vagrant init box_name(さっき保存したboxの名前)
$ vagrant up

※ちなみにboxはここに保存されています。

$ ls /home/user_name/.vagrant.d/boxes/

エラー対処

mount: unknown filesystem type 'vboxsf'

vagrantでmountエラーが出た時の対処

参照

How To Install Ruby on Rails with rbenv on Debian 8