Rubyの配列扱うときのtips

RubyもしくはRailsで配列を扱う時のtips

Rubyのメソッド

each_with_index

eachと同じ感じなんだけど、何番目かっていう数字を一緒に取れる。ループの外で i = 0 と定義して、ループの中で i += 1 とかやらなくておk。ブロックの第一引数が配列の要素で、第二引数が配列のインデックスです。

%w(a b c d).each_with_index do |value, index|
  p value
  p index
end

実行結果

"a"
0
"b"
1
"c"
2
"d"
3

all?

ブロックをとって、各要素に対して条件を指定して、全てが true だったら true を返す。

[1,2,3,4].all? do |value|
  value > 0
end

実行結果

true

any?

ブロックをとって、各要素に対して条件を指定して、1つでも true だったら true を返す。

[1,2,3,4].any? do |value|
  value == 3
end

実行結果

true

配列から、特定の物を取り除く時に簡単に使える。例えば、配列をjoinしたいけど、nilは除いてからjoinしたい時とか。

irb(main):021:0> [1,2,nil,4,5,nil] - [nil]
=> [1, 2, 4, 5]

compact

配列から、nilを取り除いた配列を返す。破壊的メソッドは compact!

irb(main):021:0> [1,2,nil,4,5,nil].compact
=> [1, 2, 4, 5]

uniq

配列から重複したものを取り除きたい時。破壊的メソッドは uniq!

irb(main):022:0> [1,1,2,3,4,2,5].uniq
=> [1, 2, 3, 4, 5]

collect (map)

配列の各要素をブロックに渡し、各結果を配列にして返します。破壊的メソッドは collect! 。map と collect は同じ。

irb(main):001:0> [1,2,3,4,5].collect do |i|
irb(main):002:1*   i * 10
irb(main):003:1> end
=> [10, 20, 30, 40, 50]

index

引数の値と一致する最初の位置を返します。

irb(main):004:0> %w(a b c d e).index('c')
=> 2

Railsのメソッド

in_groups_of

引数に個数を取って、その個数ごとの配列を生成して、その配列を返してくれる。半端な部分はnilで埋めてくれる。table組むときとか超便利。日本語むずい。

 [1,2,3,4,5,6,7].in_groups_of(3) do |group|
?> p group
>> end
[1, 2, 3]
[4, 5, 6]
[7, nil, nil]
=> nil

また今度追記するわ。

Rubyの配列扱うときのtips

起動スクリプトの書き方

 Linuxでアプリケーションを自動起動したいときは起動スクリプトかいて chkconfig -add してみたいなことをする。

 どんなディストロでも起動スクリプトの書き方は同じなんだろうか(´・ω・`) Redhat, Suse, Debian, CentOSなら行けると思う。例えばPoundはインストールしても起動スクリプトは勝手に出来ないので書く。

普通な場合

# chkconfig [起動レベル] [起動時の優先度] [停止時の優先度]

自分でいれたものだったら、起動レベルは345,45あたりでおk。正直どのレベルに何を置いたらいいのか良く分かってない。起動時の優先度は、低めでいいと思う。逆に停止時は一番最初に止めたいので高めで。

下の2つはいつもテキトーに書いてます(‘A`)

# description: [説明]
# processname: [プロセス名]

起動スクリプト編集します。

$ sudo vi /etc/init.d/pound

内容。

#!/bin/sh
# chkconfig: 345 99 1
# description: Pound
# processname: pound
start(){
  echo -n "starting pound:"
  /usr/local/sbin/pound
  return 0
}
stop(){
  killall pound
  return 0
}
case $1 in
  start)
    start
      ;;
  stop)
     stop
      ;;
esac

上記のような感じに起動スクリプトを書きます。最初に関数を定義して、あとから引数によってしょりを分ける感じです。$1,$2,… で1,2,…番目の引数が取れます。この例だと、 $ sudo /etc/init.d/pound start ってやると $1 に ‘start’ がはいって start() が呼ばれます。

次に実行権限を与えます。その後、chkconfig が使えるディストロの場合と仮定して追加すると以下のようになります。

$ sudo chmod +x /etc/init.d/pound
$ sudo /sbin/chkconfig --add pound

追加されてるか確認してみます。以下のようになってれば成功です。

$ sudo /sbin/chkconfig --list|grep pound
pound           0:off   1:off   2:off   3:on    4:on    5:on    6:off

起動時にパスワード入力を求められる時

 例えば、PoundでSSLをラッピングしてると起動時にパスワードを入力する必要があります。僕はExpect使ってるんですが、もっとスマートな方法があったら教えてほしいです(´∀`)

 まず、Expect のスクリプトを書きます。Expect にちょこっと書いてあるので詳細は省略。

$ sudo vi /usr/local/etc/pound

内容。

#! /usr/bin/expect --
set timeout -1
log_file commit_log
spawn sudo /usr/local/sbin/pound
expect "Enter PEM pass phrase:"
send "pempassword\r"
interact

Enter PEM pass phrase: の部分は予め標準出力される文字列を覚えておく必要がある。そして、実行権限を与える。

$ sudo chmod +x /usr/local/etc/pound

あとは、さっきとほとんど一緒です。 /usr/local/etc/pound を実行すればPoundが立ち上がるようになってるので、それを書くだけです。restart ってのも書いてみた。

#!/bin/sh
# chkconfig: 345 99 1
# description: software proxy Pound
# processname: Pound
# created by arai@a-it.jp 070826
start(){
  echo "starting pound..."
  /usr/local/etc/pound.sh
  return 0
}
stop(){
  echo "stopping pound..."
  killall pound
  return 0
}
restart(){
  echo "restarting pound..."
  killall pound
  /usr/local/etc/pound.sh
  return 0
}
case $1 in
  start)
    start
  ;;
  stop)
    stop
  ;;
  restart)
    restart
  ;;
esac

あとはさっきと同じ様に実行権限あたえてchkconfig -add して終了。

Railsアプリをやる場合はポートごとに stop を工夫する必要があるけど lsof とか使ってスクリプト書けばおk

起動スクリプトの書き方

Railsのredirect_toでhttpsに行かない件(with pound)

 最近の運用は、ほとんど lighttpd + Pound でやってます。速度面で lighttpd の方が有利。 ab でベンチとってみても lighttpd の方が3割程高速な様子。Pound は設定も柔軟でSSLのラッパも出来るので大変よい感じです。

 さて、Railsにはssl_requirement とか SSLに関するプラグインもあったりします。request.ssl? でリクエストがsslかどうか取れたりもするので簡単に切替は出来るんですが、Poundと組み合わせるとどうも redirect_to で https に飛ばしても http に書き変わってしまう(´・ω・`) 調べてもそんな記事がちらほら出てきます。

 Poundを挟んでも、request.ssl? は使えます。でも、自分で https に redirect_to してもやっぱhttp に行っちゃうので Poundで設定。

 やりたいことは、あるURLのページだけセキュアにしたいので https に飛ばすっていう処理。

 HTTPで来たアクセスのうち、該当するURLを正規表現で書いて https にリダイレクトする処理を書いてあげればOK。ちなみに、Redirect “http://ecpplus.net” とか書いておくと、tdl 以下のディレクトリ構造はそのまま持ち越して https に飛んでくれるので、特に何も考える必要なし。素晴らしい(´∀`)

 けど、根本的な解決になってないので方法を調べる必要がある。

ListenHTTPS
  Address 192.168.100.100
  Port 443

   Service
    HeadRequire "Host: ecpplus.net"
    BackEnd
      Address 127.0.0.1
      Port 8000
      Timeout 120
    End
  End
End

ListenHTTP
  Address 192.168.100.100
  Port 80

  Service
    HeadRequire "Host: ecpplus.net"
    URL "/(blog|diary)"
    Redirect "https://ecpplus.net"
  End

  Service
    HeadRequire "Host: ecpplus.net"
    BackEnd
      Address 127.0.0.1
      Port 8000
      Timeout 120
    End
  End
End
Railsのredirect_toでhttpsに行かない件(with pound)