gotagota日記

「面白きことは良きことなり」

ローカル開発環境 ドットインストールまとめ

ローカル開発環境の構築についてドットインストールで学びましたので、そのメモ。
完全に自分用なので、あしからずですー。

手順

  1. $ vagrant init chef/centos-6.5
  2. Vafrantfile を編集。
    -> IPアドレスの設定(コメントを外して、数値を少しいじる)
  3. $ vagrant up で先ほどの設定をもとにマシンを立ち上げる
  4. $ vagrant sshssh接続
  5. $ sudo yum update -y
  6. $ sudo vi /etc/resolv.conf
    -> 一行目に options single-request-reopen を加えて保存(既に書いてある場合は要らない。)
  7. $ sudo service iptables stopファイアウォール設定を切る。 $ sudo chkconfig iptables off とすると再起動後もoffのままになる。
  8. $ yum list installed | grep httpdでサーバーがインストールされてるか調べる -> インストールされてなければ $ sudo yum install -y httpd でインストール
  9. $ sudo service httpd start でサーバーを起動。 $ sudo chkconfig httpd on とすると再起動するたびにサーバが立ち上がった状態にできる。
    1. で設定したIPアドレスにブラウザでアクセスするとサーバが起動しているのがわかる
  10. $ sudo chown -R vagrant:vagrant /var/www/html でアクセス権を変更する
  11. Filezila を立ち上げ、サイトマネージャーを開き、以下を設定し、接続する。

    f:id:gotagotagoat:20140926022530p:plain

    -> ホスト: 2. で設定したIPアドレス
    -> プロトコル: SRTP - SSH File Transfer Protocol
    -> ログオンの種類: 通常
    -> ユーザ: vagrant
    -> パスワード: vagrant
  12. /var/www/htmlに移動する。
  13. Create new file で「index.html」を作成する。
  14. 「index.html」の編集を好きなエディタで行うため、 FileZilla の設定を変更する。
    -> 設定を開き、ファイルの編集で「カスタムエディタを使用」にチェックをして、使いたいエディタを選択する。
  15. 「index.html」を編集してアップロードすると、ブラウザをリロードすると「index.html」の内容が表示される。
  16. 毎度IPアドレスを打ち込むのは面倒なため、Hosterで設定していく。
    -> セット名は自分が把握できる名前で好きなのを
    -> ホスト名も好きなのを(アドレスになる)
    -> IPには 2. で設定したIPアドレスを入れる
  17. yum の更新 以下のリンクアドレスはOSに合うように適宜置き換えてね。
    -> $ wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm で epel をダウンロード。
    -> $ wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm で remi をダウンロード
    -> $ sudo rpm -Uvh epel-release-6-8.noarch.rpm で epel をインストール
    -> $ sudo rpm -Uvh remi-release-6.rpm で remi をインストール
  18. 設定ファイルを編集する -> $ sudo vi /etc/yum.repos.d/epel.repo で 「enabled=1」を「enabled=0」も変更する。

PHPと関連ソフトをインストールし、設定ファイルをいじる

  1. $ sudo yum --enablerepo=remi install -y php php-devel php-mysql php-mbstring php-gd でインストール
  2. $ sudo vi /etc/php.ini でファイルを編集していく。
  3. 【エラーログの設定】 -> エラーログの場所を次のように設定「error_log = /var/log/php.log」
  4. 【日本語系の扱いの設定】 -> 「mbstring.Language = Japanese」のコメントを外す
    -> 「mbstring.internal_encoding = UTF-8」に書き換える
    -> 「mbstring.http_input = auto」のコメントを外す
    -> 「mbstring.detect_order = auto」に書き換える
    -> expose_php は On ではなく Off にする
  5. タイムゾーンの設定】 -> timezone で検索(/timezone)して「date.timezone = Asia/Tokyo」にして、コメントを外す
  6. 設定を有効にするため Web サーバーを、再起動する。$ sudo service httpd restart

MySQLをインストールし、設定ファイルをいじる

  1. $ sudo yum install -y --enablerepo=remi mysql-server
  2. $ sudo vi /etc/my.cnf でファイルを編集していく。 最初のコメントの上の行に以下をコピペ。
    character_set_server=utf8
    default-storage-engine=InnoDB
    innodb_file_per_table
    [mysql]
    default-character-set=utf8
    [mysqldump]
    default-character-set=utf8
  3. $ sudo service mysqld startMySQL を起動する。
  4. $ /usr/bin/mysql_secure_installation パスワードだけ設定して、あとはリターンキーでおk
  5. せっかくなので再起動時にも有効にしたいので、$ sudo chkconfig mysqld on
  6. 起動してみる $ mysql -u root -p

postgresql をインストールする

  1. $ sudo yum install http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-redhat93-9.3-1.noarch.rpm -> リポジトリの追加
  2. $ sudo yum -y install postgresql93-server postgresql93-contrib -> インストール
  3. $ sudo service postgresql-9.3 initdb -> データベースの初期化
  4. $ sudo chkconfig postgresql-9.3 on -> 起動時自動起動を on
  5. $ sudo service postgresql-9.3 status で状態を確認し、 stopped ならば $ sudo service postgresql-9.3 start で起動
  6. $ sudo passwd postgres でパスワードを適当に変更
  7. $ su - postgres でログイン
  8. $ psql --version でバージョンを確認できる
  9. $ psqlpostgreSQL が立ち上がる
  10. create user vagrant createdb password '***********' login; でユーザを作る
  11. \qpostgreSQL から抜ける

ruby を rbenv を利用してインストールする

  1. $ sudo yum install -y git で git をインストール
  2. $ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
  3. $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
  4. $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
  5. shell を再起動し $ rbenvと打って確かめる
  6. $ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-buildruby-build をインストール
  7. コンパイラーを入れてない場合は、$ sudo yum -y install gcc でインストール
  8. $ rbenv install ... で入れたいバージョンいれ、 $ rbenv rehash
  9. $ rbenv global ...ruby を設定する

rails をインストールする

  1. gem を更新する $ gem update --system
  2. rails をインストール $ gem install rails --no-ri --no-rdoc -V
  3. $ rbenv rehash した後、 $ rails -v で確認できれば成功。

heroku を使う

  1. herokuでアカウント登録しておく
  2. $ wget -qO- https://toolbelt.heroku.com/install.sh | sh
  3. $ echo 'PATH="/user/local/heroku/bin:$PATH"' >> ~/.bash_profile
  4. $ source ~/.bash_profile
  5. $ heroku --version
    -> 自分の場合、 -bash: heroku: コマンドが見つかりません とエラーが出たので調べると、 $ sudo ln -s /usr/local/heroku/bin/heroku /usr/bin/heroku とやってパスを通せばいいらしい。
    -> 参考URL : Heroku command not found - Stack Overflow
  6. $ ls .ssh/ -> 「id_rsa」 と 「id_rsa.pub」 のペア鍵がなければ、$ ssh-keygenで作成する。
  7. $ heroku login -> heroku に登録した時のメールアドレスとパスワードを入力

『たのしいruby 第4版』第21章 Procクラス

第21章 Procクラス

模範解答はこちら

(1)

問題

Array#collect のような動作をする my_collect メソッドを定義しろ、という問題です。

私的解答
def my_collect(obj, &block)
  ary = []
  obj.each do |i|
    ary << block.call(i)
  end
  ary
end
ary = my_collect([1, 2, 3, 4, 5]) do |i|
  i * 2
end
p ary #=> [2, 4, 6, 8, 10]

引数で受けた配列を、 each メソッドで1つずつ引数で受けたブロックで処理します。

(2)

省略。

(3)

問題

実行するたびにそれまでに与えられた call メソッドの引数の合計を返す Proc オブジェクトを返す accumlator メソッドを定義しろ、という問題です。

私的解答
def accumlator
  total = 0
  Proc.new do |i|
    total += i
  end
end
acc = accumlator
p acc.call(1) #=> 1
p acc.call(2) #=> 3
p acc.call(3) #=> 6
p acc.call(4) #=> 10

Proc#call メソッドを呼び出した時の引数がブロック変数となるので、メソッド内で定義したローカル変数にどんどこ足せるように式を書けばおk。

『たのしいruby 第4版』 第20章 TimeクラスとDateクラス

第20章 TimeクラスとDateクラス

模範解答はこちら

(1)

問題

「"2013年5月30日午後8時17分50秒"」といったように、「年・月・日・時・分・秒」を使った時刻の文字列を Time オブジェクトに変換して返す jparsedate メソッドを定義しろ、という問題です。

私的解答
require 'time'
require 'date'

def jparsedate(str)
  ary = str.split(/\D+/)
  year = ary[0]
  month = ary[1]
  day = ary[2]
  if str =~ /午後|pm/i
    hour = ary[3].to_i + 12
  else
    hour = ary[3]
  end
  min = ary[4]
  sec = ary[5]
  Time.mktime(year, month, day, hour, min, sec)
end
p jparsedate("2013年5月30日午後8時17分50秒") #=> 2013-05-30 20:17:50 +0900

まず、与えられた文字列を数字以外の部分(=漢字部分)で区切って配列にします。
こうすることで単純にインデックス通りに「年・月・日・時・分・秒」になるのですが、「時」だけはちょっと工夫がいります。
午前午後を正規表現で判断して、午後かpmが含まれていれば12を足して24時間表記に直しています。

(2)

問題

Unix の「ls -t」コマンドのように、指定ディレクトリの下にあるファイルを時刻の順に並べ替える ls_t メソッドを定義しろ、という問題です。

私的解答
require 'time'
require 'date'

def ls_t(path)
  ary = []
  returnStr = ''
  Dir.open(path) do |dir|
    dir.each do |name|
      if FileTest.file?(name)
        ary << name
      end
    end
  end
  ary.sort_by!{|item| File.ctime(item)}.each do |str|
    returnStr << "#{ary.index(str)+1}番目: #{str}\n"
  end
  returnStr
end
puts ls_t("./")

ディレクトリを開いて、ファイルを空の配列に追加していきます。
それを sort_by メソッドを用いて最後に更新された順に並べ替え、空の文字列に追加していきます。

(3)

問題

Date クラスを用いて今月の1日と月末の日付と曜日を求め、以下のような形式でカレンダーを表示させろ、という問題です。

      Sep 2014       
Su Mo Tu We Th Fr St
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
私的解答

この問題はかなり骨が折れました。。。
なので(?)、ほとんどこちらを参考にさせていただきました。

以下、上記のブログを参考にしつつ自分なりにアレンジしました。

require 'time'
require 'date'

class Calender
  def initialize(year=Date.today.year, month=Date.today.month)
    @firstDay = Date.new(year, month, 1)
    @lastDay = Date.new(year, month, -1).day
    @wday = @firstDay.wday
    @weeks = (@wday + @lastDay + 6) / 7
  end

  def calAry
    calAry = (0...@weeks).map do |i|
      day = i * 7 - @wday + 1
      if day <= 0
        [nil] * @wday + (1..7 - @wday).to_a
      elsif day + 7 > @lastDay
        (day..@lastDay).to_a
      else
        (day..day + 6).to_a
      end
    end
  end

  def putCal
    header = @firstDay.strftime('%b') + "\s" + @firstDay.strftime('%Y')
    puts header.center(21)
    puts "Su Mo Tu We Th Fr St"
    calAry.each do |week|
      puts week.map {|d| d ? sprintf('%2d', d) : '  '}.join(' ')
    end
  end
end
sample = Calender.new
sample.putCal

まず、年月の指定があれば、引数で指定できるようにします。デフォルトなら現時点の年月です。
次に、
@firstDay に1日の日付,
@lastDay に月末の日付,
@wady に1日の曜日,
@weeks にその月が何週間あるか,
をそれぞれインスタンス変数にぶち込みます。これは @weeks 以外はやらなくてもいいのですが、何を扱ってるのかわかりやすくするためにあえて変数を用意しました。

calAry メソッドでは、7日間ごとの配列を作っています。
if day <= 0で最初の週を求めています。
elsif day + 7 > @lastDayで最後の週を求めています。

putCal メソッドは、カレンダー形式に出力する部分を担っています。 変数headerに月と西暦を入れて、それを center メソッドを用いて、中央寄せで出力します。
曜日は普通に出力して、日付は一週間ごとの配列 calAry を each メソッドで1つずつ取り出したものを三項演算子を用いつつ sprintf メソッドでいい感じに整えて出力します。

『たのしいruby 第4版』第18章 FileクラスとDirクラス

第18章 FileクラスとDirクラス

模範解答はこちら

(1)

問題

変数$:を使ってRubyが利用できるライブラリのファイル名を順に出力するメソッド print_libraries を定義しろ、という問題です。

私的解答
def print_libraries
  str = ''
  $:.each do |i|
    str << i + "\n"
  end
  return str
end
puts print_libraries

なんかしらを勘違いした結果、上記のような解答になりました(笑)
これだと、単純にディレクトリが出力されて終わりですね。
やり直そうにも模範解答が目に焼き付いてしまったので省略します。。。

(2)

問題

Unixの du コマンドのような挙動のメソッド du を定義しろ、という問題です。

私的解答

def du(path)
  byteSize = 0
  Dir.glob(path<<("**/*")) do |name|
    byteSize += File.size(name)
  end
  byteSize
end
puts du("./")

Dir#glob メソッドを用います。その際、**/*ワイルドカードを path にくっつけることで、指定ディレクトリ以下のすべてのファイル名を取得します。
そんで、File#size メソッドで容量を求め、どんどこ足しあわせていきます。

『たのしいruby 第4版』第17章 IOクラス

第17章 IOクラス

模範解答はこちら

(1)

問題

テキストファイルからデータを読み込んで次の処理を行うスクリプトを作成しろ、という問題です。

私的解答
Twinkle, twinkle, little star,
How I wonder what you are!
Up above the world so high,
Like a diamond in the sky.
Twinkle, twinkle, little star,
How I wonder what you are!
When the blazing sun is gone,
When he nothing shines upon.
Then you show your little light,
Twinkle, twinkle, all the night.
Twinkle, twinkle, little star,
How I wonder what you are!
file = File.read('twinkle.txt')

# (a) 行数を数える
file.each_line do |line|
  printf("%3d %s", file.lineno, line)
end

# (b) 単語数を数える
ary = file.split(/\s+/)
p ary.size

# (c) 文字数を数える
ary = []
file.each_char { |ch| ary << ch }
p ary.size

模範解答とは趣がだいぶ違いますが(笑)
(a)では、 each_line メソッド使いつつ、printf メソッド用いて行頭に行番号を付しています。
(b)では、配列に変換して size メソッドを使いました。
(c)ですが、これだと空白も一文字としてカウントしてしまうので、改善が必要か・・・と思ったのですが、模範解答もほぼ変わらなさそうなのでいいのか???

(2)

問題

テキストファイルからデータを読み込んで次の条件に従って上書きするスクリプトを作成しろ、という問題です。

私的解答

file = File.read('twinkle.txt')

# (a) 行を逆順に並べ替える
file2 = file.dup
ary = []
file2.each_line { |line| ary << line }
puts ary.reverse

# (b) 最初の一行だけを残して残りを削除
file2 = file.dup
ary = []
file2.each_line { |line| ary << line }
ary.delete_at(0)
p ary

# (c) 最後の一行だけを残して残りを削除
file2 = file.dup
ary = []
file2.each_line do |line|
  ary << line
end
ary.delete_at(-1)
p ary

まず、元のテキストデータを本当に上書きするといろいろめんどくさいので、 dup メソッドでメモリ上にコピーしました。
(a)では、単純に reverse メソッドと用います。
(b)では、delete_at メソッドで一行目を指定して削除します。
(c)では、(b)と同じように delete_at メソッドを用い引数に -1 を指定して最終行だけ削除します。

(3)

問題

Unixで使われる tail コマンドと似たことができるメソッド tail を定義しろ、という問題です。

私的解答
def tail(lineNum, fileName)
  ary = []
  File.read(fileName).each_line { |line| ary << line }
  return ary[-lineNum..-1]
end
puts tail(3, 'twinkle.txt')

行ごとに配列に入れてから、ary[-lineNum..-1] で最終行から数えて指定行数分だけ指定しています。

『たのしいruby 第4版』第16章 正規表現(Regexp)クラス

第16章 正規表現(Regexp)クラス

模範解答はこちら

(1)

問題

「ローカルパート@ドメイン名」といった電子メールアドレス文字列から、ローカルパートを$1、ドメイン名を$2として取得する正規表現を作れ、という問題です。

私的解答
def getEMAddress(str)
  str =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  localPart = $1
  domainName = $2
  return "Local part is '#{localPart}'. Domain name is '#{domainName}'"
end
p getEMAddress("info@example.com") #=> "Local part is 'info'. Domain name is 'example.com'"

メールアドレスの正規表現に関しては完全な定義が難しいらしいので、ある程度わりきる必要がありそうです。

(2)

問題

正規表現は難しい! なんて難しいんだ!」という文字列を、「正規表現は簡単だ! なんて簡単なんだ!」という文字列に変換しろ、という問題です。

私的解答

str = "正規表現は難しい! なんて難しいんだ!"
p str.gsub(/難しいんだ/, "簡単なんだ").gsub(/難しい/, "簡単だ") #=> "正規表現は簡単だ! なんて簡単なんだ!"

いっぺんに置き換えるベストな正規表現が思い浮かばなかったので、二回にわけてみたところ模範解答と同じことしてました(笑)

(3)

問題

アルファベットとハイフンから成る文字列を与えられると、ハイフンで区切られた部分を Capitalize するメソッド word_capitalize を定義しろ、という問題です。

私的解答
def word_capitalize(str)
  newAry = []
  ary = str.split(/\-/)
  ary.each do |w|
    newAry << w.capitalize
  end
  return newAry.join('-')
end
p word_capitalize("in-reply-to") #=> "In-Reply-To"
p word_capitalize("X-MAILER") #=> "X-Mailer"

配列に分解した後もう一度ハイフンでつないでます。
模範解答のように、チェインメソッドの使用によって、一行でも書けるのでこの点は記憶に刻みこみたいです。

『たのしいruby 第4版』第15章 ハッシュ(Hash)クラス

第15章 ハッシュ(Hash)クラス

模範解答はこちら

(1)

問題

曜日を表す英語と日本語との対応を表すハッシュ wday を作成しろ、という問題です。

私的解答
wday = {:sunday => "日曜日", :monday => "月曜日", :tuesday => "火曜日", :wednesday => "水曜日", :thursday => "木曜日", :friday => "金曜日", :suturday => "土曜日" }
p wday[:sunday] #=> "日曜日"
p wday[:monday] #=> "月曜日"
p wday[:thursday] #=> "木曜日"

シンボルを利用しました。
模範解答のように見やすさにも考慮してコーディングするのも大事ですよね・・・。反省。

(2)

問題

(1)のハッシュ wday のペアの数を数えろ、という問題。

私的解答

wday = {:sunday => "日曜日", :monday => "月曜日", :tuesday => "火曜日", :wednesday => "水曜日", :thursday => "木曜日", :friday => "金曜日", :suturday => "土曜日" }
p wday.size #=> 7

size メソッドを使います。

(3)

問題

(1)のハッシュを使って、

「sunday」は日曜日のことです。
「monday」は月曜日のことです。
   :
   :

という文字列を出力させろ、という問題です。

私的解答
wday = {:sunday => "日曜日", :monday => "月曜日", :tuesday => "火曜日", :wednesday => "水曜日", :thursday => "木曜日", :friday => "金曜日", :suturday => "土曜日" }
wday.each do |key, value|
  puts "#{key}」は#{value}のことです。"
end

模範解答を見ると二度手間のような気がしてならないのですが、これはこれでメリットがあるのかな・・・?
深いです。

(4)

問題

空白とタブと改行(正規表現で言えば「/\s+/」)で区切られた文字列をハッシュに変換する str2hash メソッドを定義しろ、という問題です。

私的解答
def str2hash(str)
  strAry = str.split(/\s+/)
  hash = {}
  strAry.each do |s|
    nextIndex = strAry.index(s) + 1
    hash.store(s, strAry[nextIndex]) if strAry.index(s) % 2 == 0
  end
  return hash
end
p str2hash("blue 青 white 白\nred 赤")

まず文字列を「/\s+/」で区切って配列にしてから、 Hash#store メソッドを使ってインデックスが0か偶数のものをキーとして、奇数のものを値としてハッシュに追加していきます。

ただ、これだとどうも複雑になりすぎてるので、配列から指定した数だけを取り出す便利なメソッドはないものかとぐぐりますと each_slice というドンピシャメソッドがありました。

以下、使用例。

参考URL Ruby の配列で n 個ずつの要素を扱いたい - Qiita
def str2hash(str)
  strAry = str.split(/\s+/)
  hash = {}
  strAry.each_slice(2) do |a, b|
    hash.store(a, b)
  end
  return hash
end
p str2hash2("blue 青 white 白\nred 赤")

これでかなりすっきりしたんではないかと思います。