Rails風味のRuby(その9)

WED(WeekEndDevelopers)のぽんたです。

開発スキルのないSIerからソフトウェアスキルを取得するため、WEDでモノづくりを計画しています。詳しい経緯はここ
※現在はruby on railsチュートリアル(ここから)を進めていってます。

最近railsの進捗がめっちゃ悪いです。。。少しずつですがなんとか進めていってます。。

継承は強力な概念ですが、もし仮に継承を使わずにpalindrome?メソッドをStringクラス自身に追加して(つまりStringクラスを拡張して)、より自然な方法で使えるとしたら、わざわざWordクラスを作らなくてもpalindrome?をリテラル文字列に対して直接実行できるようになるはずです。そんなことが可能なのでしょうか

?> "level".palindrome?
NoMethodError: undefined method `palindrome?' for "level":String
  from (irb):15

驚いたことに、Rubyでは組み込みの基本クラスの拡張が可能なのです。Ruby のクラスはオープンで変更可能であり、クラス設計者でない開発者でもこれらのクラスにメソッドを自由に追加することが許されています。

?> class String
>>   # 文字列が回文であればtrueを返す
?>   def palindrome?
>>     self == self.reverse
>>   end
>> end
=> :palindrome?
?> "deified".palindrome?
=> true

例えば Web アプリケーションでは、変数が絶対に空白にならないようにしたくなることがよくあります (ユーザー名などはスペースやその他の空白文字になって欲しくないものです) ので、Railsはblank?メソッドをRuby に追加しています。 Railsの拡張は自動的にRailsコンソールにも取り込まれるので、次のようにコンソールで拡張の結果を確認できます

?> "".blank?
=> true
>> "      ".empty?
=> false
>> "      ".blank?
=> true
>> nil.blank?
=> true

演習1
palindrome?メソッドを使って、“racecar”が回文であり、“onomatopoeia”が回文でないことを確認してみてください。南インドの言葉「Malayalam」は回文でしょうか? ヒント: downcaseメソッドで小文字にすることを忘れないで。

?> class Word < String             # WordクラスはStringクラスを継承する
>>   # 文字列が回文であればtrueを返す
?>   def palindrome?
>>     self == self.reverse        # selfは文字列自身を表します
>>   end
>> end
=> :palindrome?
?> s = Word.new("racecar")
=> "racecar"
>> s.palindrome?
=> true

?> s = Word.new("onomatopoeia")
=> "onomatopoeia"
>> s.palindrome?
=> false

?> s = Word.new("Malayalam")
=> "Malayalam"
>> s.downcase.palindrome?
=> true

演習2
リスト 4.16を参考に、Stringクラスにshuffleメソッドを追加してみてください。ヒント: リスト 4.12も参考になります。

?> class String
>>   def shuffle
>>     self.split('').shuffle.join
>>   end
>> end
=> :shuffle
>> "foobar".shuffle
=> "booafr"

今回はここまで次回また続きをやっていきます^^

Rails風味のRuby(その8)

WED(WeekEndDevelopers)のぽんたです。

開発スキルのないSIerからソフトウェアスキルを取得するため、WEDでモノづくりを計画しています。詳しい経緯はここ
※現在はruby on railsチュートリアル(ここから)を進めていってます。

この章ではRubyの基礎知識を学んでいきます。(前回までの続き)
Ruby を学ぶためのツールとして、主にRailsコンソールを使っていくことにします。

実は、これまで示した多くの例の中でも、クラスを使ってオブジェクトのインスタンスを作成してきたのですが、オブジェクトを作成するところを明示的に説明していませんでした。
例えばダブルクォートを使って文字列のインスタンスを作成しましたが、これは文字列のオブジェクトを暗黙で作成するリテラルコンストラクタです(だそうです)。早速試してみましょう。

?> s = "foobar"       # ダブルクォートは実は文字列のコンストラクタ
=> "foobar"
>> s.class
=> String

少しだけJava触った事があって、コンストラクタはnew演算子を使用して、インスタンス生成時に同名のクラス名を 持つメソッドが一度だけ実行さることという理解でした。

こんな書き方でもコンストラクタっていうんだーっていうのが正直な感想です。。。 ※改めて自分の知識の浅はかさを痛感

明示的にコンストラクタを指定する場合は以下。 new使ってるのでこっちのがちょっとなんとなく感覚的にわかる気がします。

?> s = String.new("foobar")   # 文字列の名前付きコンストラクタ
=> "foobar"
>> s.class
=> String
>> s == "foobar"
=> true

配列でも同様です。

>> a = Array.new([1, 3, 2])
=> [1, 3, 2]

ハッシュの場合は若干異なります。配列のコンストラクタであるArray.new は 配列の初期値を引数に取りますが、Hash.new はハッシュのデフォルト値を引数に取ります。 これは、キーが存在しない場合のデフォルト値です。

?> h = Hash.new
=> {}
>> h[:foo]            # 存在しないキー (:foo) の値にアクセスしてみる
=> nil
>> h = Hash.new(0)    # 存在しないキーのデフォルト値をnilから0にする
=> {}
>> h[:foo]
=> 0

うーん、なんだか違和感あるけどこんなものなんですね!と理解します。。。

演習1
1から10の範囲オブジェクトを生成するリテラルコンストラクタは何でしたか? (復習です)

?> a=1..10
=> 1..10

演習2
今度はRangeクラスとnewメソッドを使って、1から10の範囲オブジェクトを作ってみてください。ヒント: newメソッドに2つの引数を渡す必要があります

>> b=Range.new(1,10)
=> 1..10

演習3
比較演算子==を使って、上記2つの課題で作ったそれぞれのオブジェクトが同じであることを確認してみてください。

>> a==b
=> true

今回はここまで次回また続きをやっていきます^^

Rails風味のRuby(その7)

WED(WeekEndDevelopers)のぽんたです。

開発スキルのないSIerからソフトウェアスキルを取得するため、WEDでモノづくりを計画しています。詳しい経緯はここ
※現在はruby on railsチュートリアル(ここから)を進めていってます。

この章ではRubyの基礎知識を学んでいきます。(前回までの続き)
Ruby を学ぶためのツールとして、主にRailsコンソールを使っていくことにします。

今回はハッシュ化とシンボルについてです。
ハッシュは本質的には配列と同じですが、インデックスとして整数値以外のものも使える点が配列と異なるそうです。

?> user = {}
=> {}
>> user["first_name"] = "Michael"
=> "Michael"
>> user["last_name"] = "Hartl"
=> "Hartl"
>> user["first_name"]
=> "Michael"
>> user["last_name"]
=> "Hartl"
>> user
=> {"first_name"=>"Michael", "last_name"=>"Hartl"}

ハッシュは配列と似ていますが、ハッシュ値では要素の「並び順」が保証されないという点があります。 また、ハッシュを使う際は次のようにキーと値をハッシュロケットと呼ばれる=> によってリテラル表現するほうが簡単です。

?> user = { "first_name" => "Michael", "last_name" => "Hartl" }
=> {"first_name"=>"Michael", "last_name"=>"Hartl"}
>> user["first_name"]
=> "Michael"
>> user["last_name"]
=> "Hartl"

ここまではハッシュのキーとして文字列を使っていましたが、Railsでは文字列よりもシンボルを使う方が普通とのこと。 例えば例えば:nameはシンボルです。 但し、ハッシュのキーとしてシンボルを採用する場合、user のハッシュは次のような場合のみ使用出来ます。

?> user = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> user[:name]
=> "Michael Hartl"
>> user[:email] 
=> "michael@example.com"
>> user[:password]  
=> nil

:passwordは空なのでnilが出力されましたね。 シンボルはカッコの中でしか使えないのかなぁというイメージ

以下のような書き方もします。

?> h1 = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h2 = { name: "Michael Hartl", email: "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h1 == h2
=> true

上記の通り

{ :name => "Michael Hartl" }

{ name: "Michael Hartl" }

は等価のコードとなります。

ハッシュの値にはほぼ何でも使うことができ、他のハッシュを使うことすらできます。

?> params = {}
=> {}
>> params[:user] = { name: "Michael Hartl", email: "mhartl@example.com" }
=> {:name=>"Michael Hartl", :email=>"mhartl@example.com"}
>> params
=> {:user=>{:name=>"Michael Hartl", :email=>"mhartl@example.com"}}
>> params[:user][:email]
=> "mhartl@example.com"
>> params[:user][:name]
=> "Michael Hartl"
>> params[:user][:pass]
=> nil

基本的には使い方は一緒だけど使わないと忘れそうです。。(既にやばいです。。。)

配列や範囲オブジェクトと同様、ハッシュもeachメソッドに応答します。 例えば、:successと:dangerという2つの状態を持つ flash という名前のハッシュについてです。

?> flash = { success: "It worked!", danger: "It failed." }
=> {:success=>"It worked!", :danger=>"It failed."}
>> flash.each do |key, value|
?>    puts "Key #{key.inspect} has value #{value.inspect}"
>> end
Key :success has value "It worked!"
Key :danger has value "It failed."
=> {:success=>"It worked!", :danger=>"It failed."}

便利なinspectメソッドについてです。これは要求されたオブジェクトを表現する文字列を返します。

演習1
キーが’one’、’two’、’three’となっていて、それぞれの値が’uno’、’dos’、’tres’となっているハッシュを作ってみてください。その後、ハッシュの各要素をみて、それぞれのキーと値を"’#{key}’のスペイン語は’#{value}’"といった形で出力してみてください。

?> flash={one:"uno",two:"dos",three:"tres"}
=> {:one=>"uno", :two=>"dos", :three=>"tres"}
>> flash.each do |key, value|
?>   puts "'#{key}'のスペイン語は'#{value}'"
>> end
'one'のスペイン語は'uno'
'two'のスペイン語は'dos'
'three'のスペイン語は'tres'
=> {:one=>"uno", :two=>"dos", :three=>"tres"}

演習2
person1、person2、person3という3つのハッシュを作成し、それぞれのハッシュに:firstと:lastキーを追加し、適当な値 (名前など) を入力してください。その後、次のようなparamsというハッシュのハッシュを作ってみてください。1.) キーparams[:father]にperson1を代入、2). キーparams[:mother]の値にperson2を代入、3). キーparams[:child]の値にperson3を代入。最後に、ハッシュのハッシュを調べていき、正しい値になっているか確かめてみてください。(例えばparams[:father][:first]がperson1[:first]と一致しているか確かめてみてください)

?> person1={first:"suzuki",last:"ichiro"}
=> {:first=>"suzuki", :last=>"ichiro"}
>> person2={first:"tanaka",last:"hanako"}
=> {:first=>"tanaka", :last=>"hanako"}
>> person3={first:"sato",last:"takashi"}
=> {:first=>"sato", :last=>"takashi"}
>> 
?> params={}
=> {}
>> params[:father]=person1
=> {:first=>"suzuki", :last=>"ichiro"}
>> params[:mother]=person2
=> {:first=>"tanaka", :last=>"hanako"}
>> params[:child]=person3
=> {:first=>"sato", :last=>"takashi"}
>> params
=> {:father=>{:first=>"suzuki", :last=>"ichiro"}, :mother=>{:first=>"tanaka", :last=>"hanako"}, :child=>{:first=>"sato", :last=>"takashi"}}
>> params[:father][:last]
=> "ichiro"
>> params[:child][:first]
=> "sato"

うーん、、一応できたけど、これを覚えておける自身がないっす。。。
今回はここまで次回また続きをやっていきます^^

Rails風味のRuby(その6)

WED(WeekEndDevelopers)のぽんたです。

開発スキルのないSIerからソフトウェアスキルを取得するため、WEDでモノづくりを計画しています。詳しい経緯はここ
※現在はruby on railsチュートリアル(ここから)を進めていってます。

この章ではRubyの基礎知識を学んでいきます。(前回までの続き)
Ruby を学ぶためのツールとして、主にRailsコンソールを使っていくことにします。

配列と範囲はいずれも、ブロックを伴うさまざまなメソッドに対して応答することができます。ブロックは、Rubyの極めて強力な機能であり、かつわかりにくい機能でもあります。

>> (1..5).each { |i| puts 2 * i }
2
4
6
8
10
=> 1..5

ループ文ですね!こんな書き方をするんですね。。。
以下のような書き方もできます!

?> (1..5).each do |i|
?>   puts 2 * i
>> end
2
4
6
8
10
=> 1..5

ブロックには複数の行を記述できます (実際ほとんどのブロックは複数行です)。RailsチュートリアルではRuby共通の慣習に従って、短い1行のブロックには波カッコを使い、長い1行や複数行のブロックにはdo..end記法を使っています。

?> (1..5).each do |number|
?>   puts 2 * number
>>   puts '__'
>> end
2
__
4
__
6
__
8
__
10
__
=> 1..5

変数に「0」から「対象のオブジェクトが持つ数値 - 1」を順に代入しながら「{」から「}」までの処理(又は「do」から「end」までの処理)を実行します

>> 3.times { puts "Betelgeuse!" }
Betelgeuse!
Betelgeuse!
Betelgeuse!
>> (1..5).map { |i| i**2 }
=> [1, 4, 9, 16, 25]
>> %w[a b c]
=> ["a", "b", "c"]
>> %w[a b c].map { |char| char.upcase }
=> ["A", "B", "C"]
>> %w[A B C].map { |char| char.downcase }
=> ["a", "b", "c"]

mapブロックで宣言した引数に対してメソッドを呼び出す場合、以下のように表現することができます。

?> %w[A B C].map(&:downcase)
=> ["a", "b", "c"]

実は以下のテストコードにもdoがあることから「ブロックである」ことがわかります。
テストが実行されるときにブロック内の文が実行される、ということが理解できます。

$ cat test/controllers/static_pages_controller_test.rb 
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest
  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Ruby on Rails Tutorial Sample App"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
  end
end

覚えてなかったですが、過去に書いたコードも読み解く事が出来ます!

('a'..'z').to_a.shuffle[0..7].join

順を追ってこのコードを組み立ててみると、動作がよくわかります。

>> ('a'..'z').to_a                     # 英小文字を列挙した配列を作る
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
>> ('a'..'z').to_a.shuffle             # シャッフルする
=> ["l", "k", "b", "f", "h", "p", "j", "q", "w", "g", "u", "m", "v", "z", "s", "o", "t", "c", "i", "y", "a", "n", "x", "d", "e", "r"]
>> ('a'..'z').to_a.shuffle[0..7]       # 配列の冒頭8つの要素を取り出す
=> ["p", "s", "b", "f", "i", "e", "d", "h"]
>> ('a'..'z').to_a.shuffle[0..7].join  # 取り出した要素を結合して1つの文字列にする
=> "vtsrngkb"

演習1
範囲オブジェクト0..16を使って、各要素の2乗を出力してください。

?> (1..16).map { |i| i**2 }  
=> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256]  

演習2
yeller (大声で叫ぶ) というメソッドを定義してください。このメソッドは、
文字列の要素で構成された配列を受け取り、各要素を連結した後、大文字にして結果を返します。
例えばyeller(['o' , 'l' , 'd'])と実行したとき、"OLD"という結果が返ってくれば成功です。
ヒント: mapとupcaseとjoinメソッドを使ってみましょう。

あれ?map使わなくてもできるのでは??

>> def yeller(s)
>>     puts s.join.upcase
>> end
=> :yeller
>> yeller(['o' , 'l' , 'd'])
OLD
=> nil

やっぱり出来た。

一応mapを使ってやってみます。sが多いなぁ・・・

>> def yeller(s)
>>    puts s.map { |s| s.upcase }.join
>> end
=> :yeller
>> yeller(['o' , 'l' , 'd'])
OLD
=> nil

演習3
random_subdomainというメソッドを定義してください。 このメソッドはランダムな8文字を生成し、文字列として返します。 ヒント: サブドメインを作るときに使ったRubyコードをメソッド化したものです。

>> def random_subdomain
>>     puts ('a'..'z').to_a.shuffle[0..7].join
>> end
=> :random_subdomain
>> 
?> random_subdomain
kybjohre

答え合わせしようとしたら、数字も含めたものが出てきました。
確かにランダムは8文字ってだけ書いてあるので数字も考えないといけなかったですね・・・

?> def random_subdomain
>>     puts ('a'..'z').to_a.concat((0..9).to_a).shuffle[0..7].join
>> end
=> :random_subdomain
>> random_subdomain
keac2vqf

今は小文字だけだけど、大文字も含めると以下のようになるのかな?

?> def random_subdomain
>>     puts ('a'..'z').to_a.concat(('A'..'Z').to_a).concat((0..9).to_a).shuffle[0..7].join
>> end
=> :random_subdomain
>> random_subdomain
8dOYBoLU
=> nil
>> 

出来た出来た!これが正式回答ということで!w
※concatメソッドは、Stringクラスで用意されている文字列や配列同士を結合します。

演習4
以下のコードの「?」の部分を、それぞれ適切なメソッドに置き換えてみてください。
ヒント:split、shuffle、joinメソッドを組み合わせると、メソッドに渡された文字列 (引数) をシャッフルさせることができます。

>> def string_shuffle(s)
>>   s.?('').?.?
>> end
>> string_shuffle("foobar")
=> "oobfra"

以下の通り修正。

?> def string_shuffle(s)
>>   s.split('').shuffle.join
>> end
=> :string_shuffle
>> string_shuffle("foobar")
=> "obaofr"
>> string_shuffle("foobar")
=> "robaof"

一応2回string_shuffle("foobar")を実行してみたけど、ちゃんと出来ました!

今回はここまで!次回もこの続きをやっていきます!では^^

Rails風味のRuby(その5)

WED(WeekEndDevelopers)のぽんたです。

開発スキルのないSIerからソフトウェアスキルを取得するため、WEDでモノづくりを計画しています。詳しい経緯はここ
※現在はruby on railsチュートリアル(ここから)を進めていってます。

前回から4章に入ってます。この章ではRubyの基礎知識を学んでいきます。
Ruby を学ぶためのツールとして、主にRailsコンソールを使っていくことにします。

今回よりRailsアプリケーションを書くために重要となる、いくつかのRubyのデータ構造について説明します。

splitメソッドを使うと、文字列を自然に変換した配列を得ることができます。

>> "foo bar     baz".split     # 文字列を3つの要素を持つ配列に分割する
=> ["foo", "bar", "baz"]

splitで文字列を区切って配列にするときにはデフォルトで空白が使われますが、次のように他の文字を指定して区切ることもできます。

"fooxbarxbaz".split('x')

配列に格納してみる。
マイナス使えるんですねー。これは非常に奇妙ですね。。。

?> a = [42, 8, 17]
=> [42, 8, 17]
>> a[0]
=> 42
>> a[1]
=> 8
>> a[2]
=> 17
>> a[-1]  # 配列の添字はマイナスにもなれる!
=> 17

Rubyでは、角カッコ以外にも配列の要素にアクセスする方法が提供されてるそうです。

?> a
=> [42, 8, 17]
>> a.first
=> 42
>> a.second
=> 8
>> a.last
=> 17
>> a.last == a[-1]    # == を使って比較する
=> true

他の言語とも似たよう感じですが、演算子の振る舞いを確認する

?> x = a.length
=> 3
>> x == 3
=> true
>> x == 1
=> false
>> x != 1
=> true
>> x >= 1
=> true
>> x < 1
=> false

もちろん上記コードの最初の行のlengthメソッド以外にも、さまざまなメソッドに応答します。

>> a
=> [42, 8, 17]
>> a.empty?
=> false
>> a.include?(42)
=> true
>> a.sort
=> [8, 17, 42]
>> a.reverse
=> [17, 8, 42]
>> a.shuffle
=> [8, 17, 42]
>> a
=> [42, 8, 17]

メソッドの末尾に!をつけると配列がその内容になります

>> a
=> [42, 8, 17]
>> a.sort!
=> [8, 17, 42]
>> a
=> [8, 17, 42]

また、pushメソッド、または、<<演算子を使って配列に要素を追加することもできます。

>> a.push(6)
=> [8, 17, 42, 6]
>> a << 7
=> [8, 17, 42, 6, 7]
>> a << "foo" << "bar"
=> [8, 17, 42, 6, 7, "foo", "bar"]

結合も以下の通りできる

>> a
=> [8, 17, 42, 6, 7, "foo", "bar"]
>> a.join                       # 単純に連結する
=> "8174267foobar"
>> a.join(', ')                 # カンマ+スペースを使って連結する
=> "8, 17, 42, 6, 7, foo, bar"

範囲 (range) は、配列と密接に関係しています。to_aメソッドを使って配列に変換すると理解しやすいと思います。

>> 0..9
=> 0..9
>> (0..9).to_a            # 丸カッコを使い、範囲オブジェクトに対してto_aを呼ぶ
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

範囲は、配列の要素を取り出すのに便利です。こんな使い方もできるみたいです。使いこなしたら便利だろうな・・・

>> a = %w[foo bar baz quux]         # %wを使って文字列の配列に変換
=> ["foo", "bar", "baz", "quux"]
>> a[0..2]
=> ["foo", "bar", "baz"]

ちなみに”%w”はスペース区切りで指定する

インデックスに-1という値を指定できるのは極めて便利です。-1を使うと、配列の長さを知らなくても配列の最後の要素を指定することができ、これにより配列を特定の開始位置の要素から最後の要素までを一度に選択することができます。

>> a = (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>> a[2..(a.length-1)] 
=> [2, 3, 4, 5, 6, 7, 8, 9]
>> a[2..-1] 
=> [2, 3, 4, 5, 6, 7, 8, 9]

演習1
文字列「A man, a plan, a canal, Panama」を ", " で分割して配列にし、変数aに代入してみてください。

>> "A man, a plan, a canal, Panama".split(,)
SyntaxError: (irb):63: syntax error, unexpected ',', expecting ')'
plan, a canal, Panama".split(,)

しまった。。シングルクォートを忘れてた・・・ ついでにaに代入します。

>> a = "A man, a plan, a canal, Panama".split(',')
=> ["A man", " a plan", " a canal", " Panama"]

演習2
今度は、変数aの要素を連結した結果 (文字列) を、変数sに代入してみてください。

>> s = a.join
=> "A man a plan a canal Panama"

演習3
変数sを半角スペースで分割した後、もう一度連結して文字列にしてください (ヒント: メソッドチェーンを使うと1行でもできます)。リスト 4.10で使った回文をチェックするメソッドを使って、(現状ではまだ) 変数sが回文ではないことを確認してください。downcaseメソッドを使って、s.downcaseは回文であることを確認してください

>> puts "It's a palindrome!" if s.split(' ').join.downcase == s.split(' ').join.downcase.reverse
It's a palindrome!
=> nil

reverseメソッドを利用して回文かどうかを確認しました。

演習4
aからzまでの範囲オブジェクトを作成し、7番目の要素を取り出してみてください。同様にして、後ろから7番目の要素を取り出してみてください。(ヒント: 範囲オブジェクトを配列に変換するのを忘れないでください)

>> ('a'..'z').to_a[7]
=> "h"

あれ?gが期待値だったんだけどなぁ・・・
0も含むから7番目を指定したいときは[6]をしていするんだな・・うっかりです。

>> ('a'..'z').to_a[6]
=> "g"

期待通り!!

後ろを指定するにはマイナス(-)を指定すると想定。 試しに添字に−1を指定してみる。

>> ('a'..'z').to_a[-1]
=> "z"

おー、いけそうだ。

?> ('a'..'z').to_a[-7]
=> "t"

今回はここまで!次回もこの続きをやっていきます!では^^

Rails風味のRuby(その4)

WED(WeekEndDevelopers)のぽんたです。

開発スキルのないSIerからソフトウェアスキルを取得するため、WEDでモノづくりを計画しています。詳しい経緯はここ
※現在はruby on railsチュートリアル(ここから)を進めていってます。

前回から4章に入ってます。この章ではRubyの基礎知識を学んでいきます。
Ruby を学ぶためのツールとして、主にRailsコンソールを使っていくことにします。

最近、バタバタしてってなかなか勉強が進んでないです(言い訳)

Railsコンソールでもメソッドを定義することはできるみたいです。
※通常はファイルで定義するのが普通みたいですが・・・

早速進めていきましょう!!

>> def string_message(str = '')
>>   if str.empty?
>>     "It's an empty string!"
>>   else
?>     "The string is nonempty."
>>   end
>> end
=> :string_message
>> puts string_message("foobar")
The string is nonempty.
=> nil
>> puts string_message("")
It's an empty string!
=> nil
>> puts string_message
It's an empty string!
=> nil

"foobar"を指定すると、"The string is nonempty."が表示されますし、
""を指定すると、"It's an empty string!"が表示されます。
最後の例を見ると分かるように、メソッドの引数を省略することも可能です。

これは「def string_message(str = '')」というコードでデフォルト値を含めているからです。
このように指定すると、str変数に引数を渡す事も渡さない事もできます。引数を渡さない場合は、指定のデフォルト値が自動的に使われます。

ここで、Rubyのメソッドには「暗黙の戻り値がある」らしいです。これは、メソッド内で最後に評価された式の値が自動的に返されることを意味します。
もちろんreturnで戻り値を指定することも可能でした。

?> def string_message(str = '')
>>   return "It's an empty string!" if str.empty?
>>   return "The string is nonempty."
>> end
=> :string_message
>> puts string_message("foobar")
The string is nonempty.
=> nil
>> puts string_message("")
It's an empty string!
=> nil

演習1
リスト 4.10のFILL_INの部分を適切なコードに置き換え、回文かどうかをチェックするメソッドを定義してみてください。ヒント: リスト 4.9の比較方法を参考にしてください。

>> def palindrome_tester(s)
>>   if s == s.reverse
>>     puts "It's a palindrome!"
>>   else
?>     puts "It's not a palindrome."
>>   end
>> end
=> :palindrome_tester
>> puts palindrome_tester("aaabbb")
It's not a palindrome.

=> nil
>> puts palindrome_tester("aaabbbaaa")
It's a palindrome!

=> nil

演習2
上で定義したメソッドを使って “racecar” と “onomatopoeia” が回文かどうかを確かめてみてください。1つ目は回文である、2つ目は回文でない、という結果になれば成功です。

>> puts palindrome_tester("racecar")
It's a palindrome!

=> nil
>> puts palindrome_tester("onomatopoeia")
It's not a palindrome.

=> nil

演習3
palindrome_tester("racecar")に対してnil?メソッドを呼び出し、戻り値がnilであるかどうかを確認してみてください (つまりnil?を呼び出した結果がtrueであることを確認してください)。このメソッドチェーンは、nil?メソッドがリスト 4.10の戻り値を受け取り、その結果を返しているという意味になります。

?> palindrome_tester("racecar").nil?
It's a palindrome!
=> true

nil?にはこんな使い方もあるんですね。っていうかこっちのほうが常套手段??
full_titleをコメントを使って、各行の振る舞いに注釈を加えてみました

$ cat app/helpers/application_helper.rb 
module ApplicationHelper

  # ページごとの完全なタイトルを返します。                   # コメント行
  def full_title(page_title = '')                     # メソッド定義とオプション引数
    base_title = "Ruby on Rails Tutorial Sample App"  # 変数への代入
    if page_title.empty?                              # 論理値テスト
      base_title                                      # 暗黙の戻り値
    else 
      page_title + " | " + base_title                 # 文字列の結合
    end
  end
end

今回はここまで!次回もこの続きをやっていきます!では^^

【番外編】情報処理試験

WED(WeekEndDevelopers)のぽんたです。

開発スキルのないSIerからソフトウェアスキルを取得するため、WEDでモノづくりを計画しています。詳しい経緯はここ
※現在はruby on railsチュートリアル(ここから)を進めていってます。

今回は番外編ということで昨日(10/20)情報処理技術者試験を受けたのでその事書きます。 かなり言い訳っぽいところの箇所もあります。。

◆内容

  • 受験した試験
    応用情報技術者試験(AP) ~ ワンランク上のITエンジニア ~
    [ Applied Information Technology Engineer Examination ]
  • 対象者像
    高度IT人材となるために必要な応用的知識・技能をもち、高度IT人材としての方向性を確立した者
  • 業務と役割
    基本戦略立案又はITソリューション・製品・サービスを実現する業務に従事し、独力で次のいずれかの役割を果たす。(詳細は割愛)
  • 期待する技術水準
    1 情報技術を活用した戦略立案に関し、担当業務に応じて次の知識・技能が要求される。(以降は割愛)
  • 試験時間・出題形式・出題数(解答数)
午前 午後
9:30~12:00(150分) 13:00~15:30(150分)
多肢選択式(四肢択一) 記述式
出題数80問(全てに解答) 出題数11問(5問に解答)

◆勉強の計画

実は僕は5回目の受験なんです・・・最初の1回目は午前問がだめで午後は採点されませんでした。
次の2回目は真面目に勉強しましたが、午前は通りましたが午後が惜敗。
3、4回目も同様に午前が通って午後がだめなパターンでした。

今回はこそは!!ということで以下のような計画を立てました。

午前問題はそこそこ通っており、毎回過去問題やってるので・・・
【午前問題】
    ・過去問を過去3年間くらいを覚えるくらいやる。(過去問題で結構同じ問題出るので)
    ・近年、時代の流れかやたらセキュリティの問題が出るような気がしているのでそこの箇所だけ知識を強化する
【午後問題】
    ・セキュリティは必須なので、しっかり対策をする
    ・選択するのに解ける可能性のあるプログラミング/組込みシステム開発の過去問題をしっかり解く

◆勉強の実績

勉強は以下の通り実施。予定通り行かないもんですね・・・(言い訳)

【午前問題】
    ・過去問を過去2年間くらいを1回ずつ実施。反復も出来てません・・・
    ・教本のセキュリティの箇所を少しだけ読み直した
【午後問題】
    ・教本のセキュリティの箇所を少しだけ読み直した(午前問題でやったことです)

◆試験の受けてみて

大学で受けたのですが2時間半の2セット座りっぱなしはきつかったっす。よくある大学の大きい教室の硬いイスだったので腰がやられます・・・。
毎回午前問題を覚えるくらい勉強して息を吐くように答え出て来れば1時間とかで終わるのになーって思ってます。毎回マックスまで時間使ってますが・・・
※この試験は終わったら途中退室できます

まぁなんとか全部考えて埋めれました。。自信は半々ってところですかね。。。毎回もっと勉強しておけばよかったという後悔が残ってしまうのが辛いところ・・。

ちなみに今日午前問だけ解答出てたので自己採点したらなんとギリギリ合格ラインにのってました!!やったー!!午後も受かってればなぁ・・・・

しかし頭フル回転させてテスト受けてみるのも半年に一回くらいだと割と楽しいものです。結果さえついてくればもっといいのですが・・
あまり言いたい事がまとまってない感じですが、今回はここまで。では^^