default eye-catch image.

文字列、%記法

[arst_toc tag=\"h3\"] 文字列の式展開 PHPと同様にダブルクォート、シングルクォートにより文字列を表現する。 前者は変数展開あり、後者は変数展開なし。 実際には文字列内の\"式展開\"で、式のto_sメソッドの評価結果が文字列に展開される。 to_sメソッドを備えていれば独自クラスでも展開できる。 hoge = 10 p \"hoge is #{hoge}\" # hoge is 10 p \'hoge is #{hoge}\' # hoge is #{a} ただ文字列の中に変数を書いただけではダメで、変数展開用の識別子がいるんだな。 パーセント記法による式展開 シングルクォート、ダブルクォート以外を使って文字列を作ることもできる。 文字列の中でエスケープ無しでシングルクォート、ダブルクォートを使えて便利。 hoge = %*THIS IS TEST STRING \"HOGEHOGE\".*% もともとシングルクォート、ダブルクォートの区別により式展開するしないが決まっていたが、 当然パーセント記法を使うと式展開をそのままでは選べない。 パーセントの後にq、またはQを付与することで式展開をするしないを選ぶことができる。 なお、デフォルトは式展開をする。つまり%Qと同じ。 fuga = 100 %q*#{fuga + 100}* # \"#{fuga + 100}\" %Q*#{fuga + 100}* # \"200\" Rubyが複雑に見えるのはコイツのせいじゃないだろうか。 文字列の型変換 文字列から整数、浮動小数点、複素数、有理数などへ変換できる。 それぞれ、to_i、to_f、to_c、to_rというメソッドが用意されている。 厄介そうなことに、型変換ができない場合、変換できるところまで変換する。 そもそも先頭の文字が変換できないなら0。 \"100\".to_i # 100 \"10ab\".to_i # 10 \"1.1.1\".to_f # 1 \"hoge\".to_i # 0 デバッグ出力と関数 文字列をデバッグ用途に出力するときはpを使う。変数内の式は展開されない。 他に、print、putsで出力できる。こちらは変数内の式が展開される。 hoge = \"100 n\" p hoge # \"100 n\" puts 100 # 100 ヒアドキュメント 変数展開なしのヒアドキュメントは以下の通り。ヒアドキュメントの開始をシングルクォートにする。 ヒアドキュメントの終了は識別子も前にスペース禁止。 hoge = 100 str = <<'DOC' #{hoge} HOGE DOC 変数展開ありのヒアドキュメントは以下の通り。開始をダブルクォートにする。 hoge = 100 str = <<"DOC" #{hoge} HOGE DOC 文字列演算 文字列は+、*に対応している。 hoge = \"HOGE\" + \"FUGA\" # \"HOGEFUGA\" fuga = \"HOGE\" * 3 # \"HOGEHOGEHOGE\" <<により文字列連結。 hoge = \"HOGE\" hoge << "FUGA" # "HOGEFUGA" 比較演算 文字列の辞書順で比較する。 \"X\" \"Y\" # false \"XXX\" < "XXY" # true "XYZ" == "XYZ" # true 文字列長 .lengthメソッドにより文字列長を返す。バイト数ではなく文字数。 \"HOGEHOGE\".length # 8 sprintfと% %演算子にはsprintf相当の機能も備わっていて混乱する。 知らないと訳がわからない。 sprintf(\"THIS IS TEST INTEGER %02d\",1) # \"THIS IS TEST INTEGER 01\" p \"THIS IS TEST INTEGER %02d\" % 1 # THIS IS TEST INTEGER 01\"

default eye-catch image.

論理値、論理演算子、自己代入

真/偽 TrueClassのインスタンスがtrue、 FalseClassのインスタンスがfalse。 NilClassのインスタンスがnil。 true.class # TrueClass false.class # FalseClass falseとnilのみ偽として評価される。 falseとnil以外は全て真として評価。 この動きにより、変数に値が入っているかどうかは、 nilと比較する必要はなく変数を評価するだけで良い。 PHPのように変数に値が入っていることをチェックする必要はない。 if文 オーソドックスなif文。 compare = true if compare then \"OK\" end if文は式なのでif文を評価すると値が返る。 評価値はif式内で最後に評価された値となる。 a = if true 1 end p a # 1 後置ifという構文。簡単にコードが短くなって便利そう。だが...、 後置ifがfalseの場合でも、変数自体は確保される。が値が入らない。 意図せず変数がnilになるコードを書く可能性がある。 未定義の変数と、確保済みだが値なしの変数は明確に異なる。 a = 1 if true p a # 1 b = 1 if false p b # nil もし偽だったら、を書きたい場合はunless構文を使う。 unless false p 1 # 1 end 単項演算子?は使える。 n = (a==10) ? true : false 論理演算子 論理演算子は最後に評価したオペランドの値を返す。 評価結果(true,false)を返さない。 x = nil && 4 # nil y = 1 || 2 # 1 自己代入 変数が真でない場合に限りその変数に値を代入する自己代入。 これは、論理演算の際どい評価順序を利用していて、何故そうなるかは深い深い海の底にある。 z = z || 1 # 1 z ||= 1 # 1 zが真でない場合、つまりzがfalseかnilの場合に、 論理和演算子の右側のオペランドである1の評価結果(=1)がzに代入される。 未確保・未定義の変数の評価結果はnilなので、 未定義・未確保の場合に限り初期値を入れることができる。 z = 10 z = z || 1 # 10 &&とand、||とor、!とnot &&とand、||とor、!とnotという風に、同じ意味の論理演算子が対で用意されている。 それぞれ評価時の優先順位が異なる。(以下のようになる) p x && z # = p (x && z) p x and z # = (p x) and z

default eye-catch image.

整数リテラルとメソッド

[arst_toc tag=\"h3\"] 命名規則1.ローカル変数 変数名により用途が決まるので理解が必要。 資格系なら\"不適切な変数名\"を見抜けるかが大事。 ローカル変数は、代入が行われたブロックまたはメソッドの中だけで有効なスコープの変数。 ローカル変数は以下から構成される。ただし数字は先に来ない。 アンダースコア「_」 英数字 以下は変数名としてN.G. # アンダースコア以外の記号「-」が使われている variable-1 # これも safe? # 先頭が数値 100_or_1000 # 定数 VARIABLE 予約後を変数として再定義することはできない。 関数内ならスコープ外のローカル変数を参照すると例外。 kuma=20 def hoge(x,y) kuma end スコープ内で定義されているが評価されていない変数を参照するとnil。 def hoge(x,y) kuma = x + y if x > 10 kuma end > hoge 20,30 => 50 > hoge 5,10 => nil 命名規則2.グローバル変数 スコープに関係なくどこからでも参照できる変数。 構成する文字はローカル変数と同じ。ただし先頭は「$」。 アンダースコア「_」 英数字 $global = 100 def fuga(a,b) $global end > fuga 10,20 => 100 リテラルの種類 Rubyのリテラルは以下。 数値 論理値 文字列 シンボル 配列 ハッシュ 範囲 正規表現 ハッシュ 数値リテラル 整数と浮動小数点を使える。符号、指数表記、基数指定が可能。 基数指定でありえない値を指定すると例外。 +100 -200 2e2 # 2 に10の2乗を掛ける => 20 5e-e # 5 に10の-3乗を掛ける => 0.05 0b10 # 2進数の10 => 2 0o10 # 8進数の10 => 8 0d10 # 10進数の10 => 10 0x10 # 16進数の10 => 16 0xfg # 16進数でgはNG 数値リテラル内で桁表現ができる。(ロケールが違うときはどうなるのだろうか?) 100_000 => 100000 有理数(Rational)、複素数(Complex)もリテラル。 有理数は既約になる。浮動小数点にしないで保持できる。 また、小数を既約分数に変換できる!(すごい過剰な感じがする...) 25/45r # (5/9) 3.14r # (157/50) 複素数は実数、虚数の指定を整数、小数を使って表現できる。 12i # (0+12i) 5.6i # (5+6i) 有理数、虚数をミックスすることもできる。 3.14ri # (0+(157/50)i) 数値クラス 数値クラスのインスタンスである。 一言に数値クラスといっても継承関係によって詳細化されている。 a = 100 a.class # Fixnum a.class.superclass # Integer a.class.superclass.superclass # Numeric 数値クラスに実装された演算子により、数値演算、比較演算を実行できるようになっている。 数値演算 代表的な2項演算子は一通り使える。 1+1 # 2 1-2 # -1 3*3 # 9 4/2 # 2 4%3 # 1 代表的な比較演算子も一通り使える。 1==1 # true 1!=5 # true 1=1 # true 怪しい演算子が用意されている。UFO演算子。 演算子の左が大きければ1、等しければ0、右が大きければ-1。 500 10 # 1 500 500 # 0 10 500 # -1 と書いてあるけど、オペランドがNumericの時の話であって、 一般には「正」「0」「負」の振り分けと考えた方が良さそう。 オペランドが比較不能な場合はnilだそうだ。 if文を使って3方分岐するときに使える。 compare = (hoge fuga) if compare == 0 # hogeとfugaが比較可能で等しいとき elseif compare > 0 # hogeとfugaが比較可能でhogeが大きいとき else # 上記以外 (比較可能でfugaが大きいときを含む) end Rubyにはインクリメント演算子、デクリメント演算子は存在しない。 ので代わりに自己代入演算子を使う。 a = 100 a += 20 # 120 a -= 30 # 90 a *= 2 # 180 数値クラスの演算子であることを意識した書き方をすると、 数値の加算を以下のように書ける。 a = 100 a .+(50) # 150 メソッド 最後に評価された値が返る。returnで返すとそこで評価が終了する。 returnを書かないと関数内を最後まで読んで何が最終評価か理解しないといけないから 明示的returnを推奨する人もいるが、無いコードも多数ある。資格系はreturn無しの様子。 def add(x,y) x+y end > add 10,20 30=> nil def predict(hoge) if (hoge) then \"OK\" else \"NG\" end end > predict false => \"NG\" 仮引数のデフォルト値を指定できる。指定した引数の数が足りない場合は例外。 def add(x,y=200) x+y end add 10 => 210 キーワード引数 仮引数に名前をつけることができる。 これによりメソッド実行時に引数としてハッシュオブジェクトを渡せるようになる。 def add(x:,y:) x+y end add (x:100,y:200) => 300 キーワード引数にない引数名を指定すると例外。 def add(x:,y:) x+y end add (x:100,z:200) # 例外 ただし、キーワード引数を定義したメソッドに任意の引数を渡すことができる。 def add(x:,y:,**z) p z x+y end add (x:100,y:200,z:300) # {z=>300} => 300

default eye-catch image.

vagrant(ubuntu/xenial64 vbox) ubuntu16にrbenv rubyをインストールするplaybook (ほぼ失敗作)

作ってみたがrbenv installにとても時間がかかるので現実的ではないと思う。 vagrantのように壊して作るのが前提ならrbenvでバージョンを切り替えられる必要はないから、 わざわざ毎回コンパイルすることはない気がする。 いずれapt-get installで直接インストールする方法を試してみる。 commonロール 実験の結果、ubuntu/xenial64 vboxに必要だったパッケージたちを入れるロール。 become: yes, become_method: sudo で実行。 --- - name: install packages apt: name=\"{{item}}\" state=present with_items: - gcc - make - libssl-dev - zlib1g-dev rbenv,rubyインストールロール ansible実行ユーザ(ubuntu)のホームディレクトリ以下にrbenvとrubyを入れるロール。 .profileに追加した内容を反映して次に進まないとエラーになる...->要改良 --- - name: retrieve the latest rbenv to ~/.rbenv git: repo=https://github.com/sstephenson/rbenv.git dest=/home/{{user}}/.rbenv accept_hostkey=yes force=yes - name: retrieve the latest ruby-build plugin to ~/.rbenv/plugins/ruby-build git: repo=git://github.com/sstephenson/ruby-build.git dest=/home/{{user}}/.rbenv/plugins/ruby-build accept_hostkey=yes force=yes - name: add path to ~/.rbenv/bin lineinfile: dest=/home/{{user}}/.profile line=\'PATH=\"$HOME/.rbenv/bin:$PATH\"\' state=present create=yes - name: add path to ~/.rbenv/plugins/ruby-build/bin lineinfile: dest=/home/{{user}}/.profile line=\'PATH=\"$HOME/.rbenv/plugins/ruby-build/bin:$PATH\"\' state=present create=yes - name: add initial evaluation of rbenv init lineinfile: dest=/home/{{user}}/.profile line=\'eval \"$(rbenv init -)\"\' state=present create=yes - name: add gem lineinfile: dest=/home/{{user}}/.gemrc line=\"gem{{COLON}} --no-ri --no-rdoc\" state=present create=yes - name: rbenv install 2.4.1 shell: bash -lc \"rbenv install 2.4.1\" - name: rbenv global 2.4.1 shell: bash -lc \"rbenv global 2.4.1\" - name: gem install bundler shell: bash -lc \"gem install bundler\"