Ruby超入門 2周目 CHAPTER11-4 ブロックの高度な話 まで

 

f:id:kkouji0224:20191027224451p:plain

 

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

昨日も寝まくりで暖房つけて寝たら石ころみたいなカッチカチの目ヤニができてたよ。こんにちは。koujiです。

 

あー!!あーあーあー!!超入門が終わっちゃうよー!!この気持ちは面白い小説とか映画が終わっちゃう感じに似てるな… 入門書でもこういう気分にさせられるんだからすごいね。世界観のある入門書ってなかなか書けないのではないでしょうか…

 

ってことで気持ちを切り替えて今日も振り返っていきまーっす!

 

インスタンス変数を簡単に操作しようぜ!!

 

class Alc
  def name
    @name
  end
  def name=(text)
    @name = text
  end
end

alc = Alc.new
p alc.name

 

vscodeから今までコピペでインデントまで反映されてたんだけど、知らぬ間に反映されなくなっちゃったからインデントなしで見難いけどすまんねっ!

 

インスタンス変数の取得と代入は今まではこんな感じで書いてきたよね。

 

attr_accesser

 

class Alc
  attr_accessor :name
end

alc = Alc.new
p alc.name

 

こんなに省略して書けちゃう… attr_accesserメソッドは「同名のインスタンス変数を戻り値とするメソッドを定義する」と「同名のインスンタンス変数へ代入するメソッドを定義する」の2つのことをやってくれちゃうメソッド!!めっちゃ便利!

 
いきなりattr_accessorから書いてみたんだけど、attr_readerとattr_writerってのもあるんだよね。
 
上にも書いたとおり、attr_accessorは両方やってくれる。
 
attr_readerは「同名のインスタンス変数を戻り値とするメソッドを定義する」
attr_writerは「同名のインスンタンス変数へ代入するメソッドを定義する」
 
class Alc
  attr_reader :name
  def name=(text)
    @name = text
  end
end

alc = Alc.new
p alc.name

 

まずattr_readerね。

def name

  @name

end

これと同じことをやってくれてるんだね。

 

class Alc
  attr_reader :name
  attr_writer :name
end

alc = Alc.new
p alc.name

 

次はattr_writerね。

def name(text)

  @name = text

end

これと同じことをやってくれるんだよ!

 

で、両方やってくれちゃうのがさっきかいたattr_accessorだぜ!

 

selfを観察!!

 

class Alc
  def me
    p self.object_id
  end
end

alc = Alc.new
p alc.object_id
alc.me

 

selfはその場所でのレシーバを返すもの!ってことでクラスのインスタンスメソッドの中でselfを呼び出すと何が返ってくるのか…?上のプログラムを実行すると下のオブジェクトIDになるね。

 

47367875712620
47367875712620

 

インスタンスメソッドmeの番号と、Alc.newで作ったオブジェクトのIDと一致してる!

なので、クラスのインスタンスメソッドの中でのselfはそのメソッドを読んだ時のレシーバと同じってことだね!

 

じゃークラスメソッドのselfはどうなるのか?

 

class Alc
  def self.me
    p self.object_id
  end
end

p Alc.object_id
Alc.me

 

結果はこんな感じ

 

47101248501500
47101248501500

 

やっぱり同じだね。なので、クラスメソッドのselfは、そのメソッドを読んだ時のレシーバと同じになるんだぜ!

 

クラスメソッドとインスタンスメソッドのインスタンス変数は別だよ!

 

class Alc
  def name
    @name = "焼酎"
  end
  def self.name
    @name = "ウォッカ"
  end
end

alc = Alc.new
puts alc.name
puts Alc.name

 

alc.name は焼酎

Alc.nameはウォッカ

 

インスタンスオブジェクトが持ってるインスタンス変数と、クラスがもつインスタンス変数って感じだね!ややこしくなくていたってシンプル!!

 

ちなみにクラス変数ってものもあって@@nameみたいに@を2つ。これはクラスで共有できるんだけど、継承したクラスでも共有するんだってよっ!

 

正規表現

 

kanagawa = ["横浜市", "川崎市", "相模原市", "大和市"]

kanagawa.each do |city|
  puts city if city.match?(/大和市/)
end

 

正規表現ってのは特定の文字列を含んでいるかを調べるのに便利!

/大和市/は正規表現オブジェクトっていうらしくスラッシュで囲んであげると正規表現オブジェクトになって、これを「パターン」というんだぜ。

 

上のプログラムは配列kanagawaを.each使って1つづつcityに代入して、後置ifでmatch?メソッドで、正規表現の/大和市/が含まれてたらputs cityって感じだね。

 

正規表現はそれだけで1冊本が書けるぐらいのものらしい。きっと奥が深いのだろう…沼の予感がする… 

 

他にも/[A-Za-z0-9]/みたいな感じで範囲指定で書けたり、/a.c/みたいな任意の1文字だったり、と色々あるみたいなので、正規表現に絞って学ぶってのをやってみるのも面白いかもしれないね… 沼な予感するけどね…

 

 

ブロックを渡す

 

def alc
  if block_given?
    puts "英語バージョン"
    yield
  else
    puts "日本語バージョン"
    puts ["焼酎", "ビール", "ハイボール", "ワイン", "日本酒"].sample
  end
end

alc do
  puts ["beer", "shochu", "highball", "wine", "sake"].sample
end

 

実はブロックってメソッドに渡せるんだよっ!!これは面白いね!上のプログラムの場合はif block_given?でblock_given?メソッドってのでブロックが渡された場合はtrue、渡されて内場合はfalseになるので、trueの場合はifでputsとyieldが実行されるね。この

yieldを使うとメソッドの中で実行する処理を、呼び出し元でブロックで書くことができちゃうんだね!

 

ブロックを引数でうけとる!

 

def alc(&b)
  b.call
end

alc do
puts "生ビールは最高だ!"
end

 

ブロックは変数に代入できちゃう!このときのブロックをProcってオブジェクトとして扱われるんだね。Procオブジェクトはブロックの処理をオブジェクト化したもの。で、このプログラムだとalc(&b)って書いてあるけど、&を引数の前に書いてあげるとブロックを受け取れるようになる。で、bに代入してcallメソッドで実行するって感じ。これも面白いねー!なにがどう面白いのか説明できないけど面白いんだよ!

 

うおーーー!!終わってしまった!!超入門の振り返りが終わってしまった−−−!!

 

すごく楽しみながら振り返ることができた… ここまで面白いなぁーと思ってブログまで書いてみたのは初めてだったんだけど、楽しい物語が終わってしまう気分だ…

 

楽しかった。あとで振り返りのまとめも書いてみよう。

 

ということでRuby超入門の振り返りはここまでっ!!

 

素晴らしい時間でした!著者の五十嵐さんもTwitterでいいねくれたり、はてなの星くれたりと嬉しかったです!ありがとうございました!

 

ってことで超入門の振り返りはこれで終わりますが、まだまだこの道は続いていくぜー!!さーて次はなにをやろうかなっ!!

 

ってことで一旦このへんで!

 

アディオス!

 

Ruby超入門 2周目 CHAPTER11-1 例外処理 まで

f:id:kkouji0224:20191027224451p:plain

 

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

マジで寝ても寝ても体が思い。まぶたが重い。頭も重い。

そんな感じ。koujiです。こんばんは。

 

今日はCHAPTER10の途中まで振り返っていこうと思いますっ!

 

例外処理だぜ!

 

puts "残高を入力してくれ!"
bank_balances = gets.to_i
puts "次の給料日までの日数を入力してくれ!"
days = gets.to_i

oneday = bank_balances / days
puts "一日あたり使える金額が#{oneday}円しかねーよ!!"

 

上のプログラムはgetsメソッドで入力を取り込んで.to_iメソッドで文字列を整数に変換して、単純に金額/日数で一日あたりの金額をだしてるんだけど、ここで日数で0を入力するとエラーが出るんだよね。

 

こんな感じ。

 

f:id:kkouji0224:20191109231955p:plain

 

エラーでZeroDivisionErrorってのがでてるね。これはonedayのところでbank_balances / daysで5000/0の0で割ろうとするときに出てる例外エラー。で、エラーが発生してるので次の行のputsは実行されないって感じだね。で、このZeroDivisionErrorは例外クラス

 

rescueで例外を処理する

 

puts "残高を入力してくれ!"
bank_balances = gets.to_i
puts "次の給料日までの日数を入力してくれ!"
days = gets.to_i

begin
oneday = bank_balances / days
puts "一日あたり使える金額が#{oneday}円しかねーよ!!"
rescue ZeroDivisionError
puts "0日ってことは#{bank_balances}円貯金できるな!やったね黒字だね!"
end

 

beginからrescueの間に例外が発生しそうな処理を書くんだね。で、rescueからendの間に例外が発生した時の処理を書く感じ。で、今回はZeroDivisionError例外を処理するので、resucue ZeroDivisionErrorって書くようにしてると。これで給料日までの日数を0で入力すると結果はこんな感じ。

 

f:id:kkouji0224:20191109233414p:plain

 

ヒャッハー!!5万貯金できるぜ!!

 

rescueをメソッド内で使う場合

 

def oneday(bank_balances, days)
oneday = bank_balances / days
puts "一日あたり使える金額が#{oneday}円しかねーよ!!"
rescue ZeroDivisionError
puts "0日ってことは#{bank_balances}円貯金できるな!やったね黒字だね!"
end

oneday(50000, 0)
oneday(50000, 10)

 

メソッドの中で使う場合はbeginとendを省略して書いてもOK。メソッドのはじめからresucueまでのところで例外が発生したら、rescue ZeroDivisionErrorで受け取れちゃう!

 

bank_balances = 50000
days = (0..31)

days.each do |day|
oneday = bank_balances / day
puts "1日あたり使える金額が#{oneday}円しかねーよ!!"
rescue ZeroDivisionError
puts "0日ってことは#{bank_balances}円貯金できるな!やったね黒字だね!"
end

 

ちなみにブロックないでもbeginとendを省略してこんな感じで書けちゃうね!

 

例外の情報を取得できるよ!

 

bank_balances = 50000
days = (0..31)

days.each do |day|
oneday = bank_balances / day
puts "1日あたり使える金額が#{oneday}円しかねーよ!!"
rescue ZeroDivisionError => e
puts "※※※例外発生※※※"
puts "例外クラス: #{e.class}"
puts "例外メッセージ: #{e.message}"
end

 

rescue ZeroDivisionError => e このeは変数でこの場合はZeroDivisionErrorオブジェクトを代入してるね。で、putsのところでオブジェクト名.classとか.messageでクラスとメッセージを取得してるね。.classとか.messageは例外クラスで使えるメソッド!

 

ちなみにrescueは指定したクラスだけじゃなくて、サブクラスも補足できちゃうんだね。例えばZeroDivisionErrorの場合は親クラスがStandardErrorなので…

 

bank_balances = 50000
days = (0..31)

days.each do |day|
oneday = bank_balances / day
puts "1日あたり使える金額が#{oneday}円しかねーよ!!"
rescue StandardError => e
puts "※※※例外発生※※※"
puts "例外クラス: #{e.class}"
puts "例外メッセージ: #{e.message}"
end

 

こんな感じで書いてあげてもZerodivisionErrorを補足できるんだね。便利だ…

さらにちなみになんだけど、rescue => e は rescue StandardError => eと同じ。

 

raiseメソッドで例外を発生させる

 

ef rich(cash)
if cash < 0
raise "借金が#{cash}円です!"
elsif cash < 1000000
"貧困です"
elsif cash < 10000000
"小金持ちです"
else
end
end

cash = ARGV.first.to_i
rich = rich(cash)
puts "#{cash}円は#{rich}"

 

上の場合はcashがマイナスだった場合にraiseメソッドで例外を発生させてるよ。rescue使ってないので、例外が補足されないのでputsは実行されないんだね。raiseメソッドで例外メッセージのみを指定した場合はRuntimeErrorになるよっ!

 

ensureで例外があってもなくても処理を実行する

 

def rich(cash)
if cash < 0
raise "借金が#{cash}円です!"
elsif cash < 1000000
"貧困です"
elsif cash < 10000000
"小金持ちです"
else
end
end

begin
cash = ARGV.first.to_i
rich = rich(cash)
puts "#{cash}円は#{rich}"
rescue => e
puts "例外発生: #{e.message}"
ensure
puts "お金はいくらあっても足りないぜ!"
end

 

beginとrescueの間に例外が発生しそうな処理をかいてensureのところに例外があってもなくても実行する処理を書く。実行するとこんな感じ。

 

f:id:kkouji0224:20191110004418p:plain

 

見ての通りなんだけど、-5で例外を発生させても「お金はいくらあっても足りないぜ!」だし、例外にならない数にしても「お金はいくらあっても足りないぜ!」が表示されてるね。ensureは書いておくと発生の有無に関係なく実行してくれる頼もしいやつだぜ。

 

実は例外処理って便利そうだけど退屈そうだなぁ…って始める前は思ってたんだけど、2周目やってみるとこれはこれでなかなか便利というか面白いんじゃないかなって気になってきた。明日が休みだから楽しく感じるのか… いやそんなことない。1周目の時よりも面白く感じる。これは確かだ!!てか、便利だよね。

 

ってことで例外処理を振り返ってみましたー!

 

こうやって振り返ってると体のダルさを忘れられるから不思議だぜ…

 

ってことで今日はこの辺で!

 

アディオス!

Ruby超入門 2周目 CHAPTER10-1 ライブラリを使う まで

f:id:kkouji0224:20191027224451p:plain

 

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

寝ても寝てもまだまだ寝れる。もっともっと寝れる。そんな感じです。

こんばんはkoujiです。

 

今日は CHAPTER10を振り返っていくぜー!!

 

Gemを使うぜ!!

 

まずRubyの世界には3つのライブラリがあるんだ。1つは「組み込みライブラリ」2つ目はrequireメソッドを実行して使う「標準添付ライブラリ」3つ目がインストールしてつかう「Gem」だ。

 

Gemのインストール

f:id:kkouji0224:20191107214027p:plain

 

上の場合だとawesome_printってgemをインストールしているね。ターミナルで gem install Gem名って書いてあげるとインストールできるよ!installは頭文字のiだけでgem i でもOK!

 

gem installコマンドはプログラムを実行するたびにインストールする必要はないんだね。で、gem listコマンドでインストールされてるgemとそのバージョンを確認できるんだよ。こんな感じ。

 

f:id:kkouji0224:20191107214737p:plain

 

じゃーさっそくインストールしたgemを使ってみようじゃないですか。

 

require "awesome_print"
ap ["醤油ラーメン""味噌ラーメン""塩ラーメン"]

 

これを実行すると…

 

f:id:kkouji0224:20191107214907p:plain

 

こんな感じで、配列が見やすく表示されるようになるね。gem installでインストールしたものをrequire "awesome_print"で読み込んでapメソッドを使ってるね。便利だぜ。

 

もちろんGemの使い方はGemによって違ってくるので、Gemのドキュメントを読んでから使う感じ。GitHubのページが多いみたい。

 

Bundlerを使う

BundlerはBundlerのインストール→Gemfileを書く→bundle installって感じで進めていくよ。Bundlerを使うと複数のGemをインストールする必要があるときに便利だね。

 

f:id:kkouji0224:20191107221724p:plain

 

こんな感じでまずはインストール。gem install bundlerって感じだね。

 

f:id:kkouji0224:20191107222052p:plain

 

で、次にbundle initコマンドでgemfileの雛形をつくりまーす。toの後がgemfileが出来た場所になりまーす。で、gemfileを開いて編集していきまっす。

 

# frozen_string_literal: true


git_source(:github) {|repo_name"https://github.com/#{repo_name}" }

# gem "rails"
gem "pry"

 

こんな感じ。# gem "rails"とかは例なので消してもいいし#外してrailsをインストールしてもいいけど、今回は触らないでおきまっす。で、インストールしたいgemを最後に書くんだね。今回はpryをインストールしてみようってことなんで、gem "pry"って感じ。書いたら保存!

 

gemfileも書いたしインストールだ!

 

f:id:kkouji0224:20191107222641p:plain

 

bundle installコマンドを実行するとgemfileに書いたpryがインストールされる!今回はgemを1つしか書いてないけど、gemfileに複数書いた場合でも、このbundle installコマンドで一回でインストール出来ちゃう便利ものだねっ。

 

bundle installコマンドを実行すると、Gemfile.lockってフィルが作成されるんだけど、使われているGemのバージョン情報とかが記載されてるよ。GemfileとGemfile.lockはセットなんだね。Gemfileは発注書で、Gemfile.lockは納品書って考えるといいみたい!!

 

Gemfileに書かれているgemの新しいバージョンがリリースされている場合は、bundle updateコマンドを使えば、新しいバージョンのgemがインストールできて、そのバージョン情報がGemfile.lockに書き込まれるって感じ!

 

コマンドでGemのバージョン指定をして使うってこともできるみたい。新しいバージョンのgemをインストールしても古いバージョンのgemはアンインストールされないんだね。で、同じgemの複数のバージョンがインストールされてる状態になってる。で、新しいバージョンが使用されるようになってるんだけど、Gemfile.lockに書かれたバージョンでRubyを実行したい場合は… bundle exec ruby ファイル名.rbって書いてあげるとできるんだねー。

 

 ってな感じで、GemのインストールやbundlerやGemfilやGemfile.lockな感じでしたっ!Gemfile.lockって何かよくわかってなかったんだけど、Ruby超入門で説明されてて「なるほどなー」って感じだったんだよね。納品書!!

 

ってな感じで今日はこの辺で!!sinatraを振り返るか迷い中!!

 

ってことでアディオス!

 

Ruby超入門 2周目 CHAPTER9 部品を共同利用する - モジュール まで

f:id:kkouji0224:20191105195214p:plain

 

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

こんばんは。昨日からやけに寒くなってきましたね。夜中に目が覚めてガクブルでした。koujiです。

 

さーて今日からCHAPTER9を振り返っていきまーす!モジュールさんですね。

 

モジュールさん

 module Topping
    def menma
        @name += "トッピングでメンマ"
    end
    def chashu
        @name += "トッピングでチャーシュー"
    end
    def egg
        @name += "トッピングでタマゴ"
    end
    def wakame
        @name += "トッピングでわかめ"
    end
end

class SoySourceRamen
    include Topping
    def initialize
        @name = "醤油ラーメン"
    end
    def name
        @name
    end
end

class SaltRamen
    include Topping
    def initialize
        @name = "塩ラーメン"
    end
    def name
        @name
    end
end

class MisoRamen
    include Topping
    def initialize
        @name = "味噌ラーメン"
    end
    def name
        @name
    end
end

saltramen = SaltRamen.new
saltramen.chashu
puts saltramen.name

 

まずはモジュールってなんじゃらほいって感じだよね。クラスと似てるんだけど、クラスと違ってインスタンスを作ることができないんだ。メソッドを共同利用するためのものって感じかな。

 

まず書き方は見ての通りなんだけど。module 先頭大文字のモジュール名 endって感じで書くよ。中にメソッドを書く感じだね。上の場合だと@nameにチャーシューとかワカメとかタマゴを追加するってやつだね。

 

で、モジュールのメソッドをクラスで使うにはinclude モジュール名。これをクラスの中に書いておくとモジュールで定義したメソッドが実行できるようになるんだね。ちなみにincludeは入れるとか組み込むとか含むとかそんな意味らしい。そのまんまだね!!

 

で、モジュールは複数のクラスで共同利用ができるんだね。上を見てもらえばわかると思うんだけど、醤油らーめんクラスでも塩らーめんクラスでも味噌らーめんクラスでもincludeしてるんだぜっ!!これはめっちゃ便利だしわかりやすいねー。

 

こんな感じでモジュールを使うとクラス継承とは違った感じでメソッドが共同利用できるんだね。今回のらーめんプログラムはもしかしたら継承で作ったほうが違和感ないかもしれないけど、他に思いつかなかったってことで!継承でやるかモジュールでやるかは今後慣れていこうかなって感じ。

 

モジュールにクラスメソッド定義

 

module Topping
    def self.info
        "ラーメンのトッピン具材だよ"
    end

 

こんな感じでクラスの時と同じだね。.selfだね。こうやって書いてあげるとputs Topping.infoで呼び出せるよ!

 

モジュールで定数をつかう

 

module Topping
    Price = "150円"
    def self.info
        "ラーメンのトッピン具材だよ! 全部" + Price
    end

 

こんな感じで使えるね。定数は先頭が大文字ね。

 

定数を使う時はこんな感じで呼び出す。

 

puts Topping::Price

 

Topping::Priceって書いてあるようにモジュール名::定数名だね。

 

Rubyが用意しているモジュール

 

puts Math::PI
puts Math::cos(Math::PI)

 

上のはRubyが用意してくれているMathモジュールで数学計算用クラスメソッドとか定数が定義されてるみたい。リファレンスのモジュールのところに他のモジュールも書いてあるんだけどちょっと難しそうなので今回は触れずにおこう…。

 

名前空間

 

module SaltRamen
    class Ramen
        def self.info
            "自慢の塩ラーメン"
        end
    end
end
module MisoRamen
    class Ramen
        def self.info
            "自慢の味噌ラーメン"
        end
    end
end

puts SaltRamen::Ramen.info
puts MisoRamen::Ramen.info

 

同じクラス名を複数使いたいけど、別々のクラスとして定義して分けたいときはこんな感じで書いてあげるといいみたい。これを名前空間を作るって言うんだってよ!!

 

上見てもらうとわかると思うんだけど、SaltRamen::RamenとかMisoRamen::Ramenみたいな感じで使い分けができるようになるね。

 

インスタンスを作るときはクラス、作らない時はモジュールを使うと意図が伝わりやすいようだ。名前空間をわけるだけならモジュールでいいね!

 

別ファイルのクラスとかモジュールを読み込む

 

ramenmodule.rb

module Topping
    Price = "150円"
    def self.info
        "ラーメンのトッピン具材だよ! 全部" + Price
    end
    def menma
        @name += "トッピングでメンマ"
    end
    def chashu
        @name += "トッピングでチャーシュー"
    end
    def egg
        @name += "トッピングでタマゴ"
    end
    def wakame
        @name += "トッピングでわかめ"
    end
end

 

ramen.rb

require_relative "ramenmodule"
class SoySourceRamen
    include Topping
    def initialize
        @name = "醤油ラーメン"
    end
    def name
        @name
    end
end

class SaltRamen
    include Topping
    def initialize
        @name = "塩ラーメン"
    end
    def name
        @name
    end
end

class MisoRamen
    include Topping
    def initialize
        @name = "味噌ラーメン"
    end
    def namerequire_relative
        @name
    end
end

saltramen = SaltRamen.new
saltramen.chashu
puts Topping.info
puts Topping::Price
puts saltramen.name

 

さっき書いた1つのファイルをmoduleとclassで分割してみたよ。で、classの方にrequire_relativeメソッドを書いてramenmodule.rbを読み込んでToppingモジュールを使ってる感じだね。読み込む側でrequire_relativeの引数が文字列でファイル名だね。.rbは省略可だよ。例えば、これから新しいプログラムを書いて、そこからrequire_relativeで読み込むこともできちゃうわけだねぇ〜!!便利っす!

 

ちなみにrequire_relativeメソッドじゃなくてrequireメソッドを使うことも出来るんだけど、その場合はrequire "./ファイル名"と書けるみたいなんだけど、別ファイルを読み込むときはrequire_relativeがオススメらしいっす!

 

includeとrequire_relativeは似てる感じするけど…

 

include

モジュール名を渡してそのモジュールに書かれたメソッドをクラスから使えるようにするメソッド!

 

require_relative

ファイル名を渡して、そのファイルに書かれたクラスやモジュールを使えるようにするメソッドだよ!

 

って感じでちょっと駆け足気味に振り返ってみました!インスタンスを作る時と作らないときで使い分けていけばいいんだなぁー。ってのはわかったんだけど、実際にどんな場面で使い分けるのかなぁって感じなので、その辺は今後嫌でもわかってくるだろうから特にきにしないでおこう!!

 

それにしても「なるほどなぁー」って感じで面白い。

 

昨日Twitterでふと思ったんだけど「勉強」でもないし完全に「遊んでる」って感じでもないんだけど、その中間にあるような言葉ってなんだろうね?

 

そんなことを考えながら楽しんでまっす!!

 

ってことで今日はこの辺で。アディオス!!

Ruby超入門 2周目 CHAPTER8-8 メソッドの呼び出しを 制限する まで

f:id:kkouji0224:20191029231558p:plain

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

よーしご飯食べて筋トレ終わったぜ!こんばんはkoujiです。

 

じゃーさっきの続きを振り返っていきまーっす!

 

継承でクラスを分ける

 

class Drink
    def name
        @name
    end
    def name=(text)
        @name = text
    end
    def size
        @size
    end
    def size=(text)
        @size =text
    end
end

class Alc < Drink
    def alcohol_content
        @alcohol_content
    end
    def alcohol_content=(text)
        @alcohol_content = text
    end
end

drink = Drink.new 
drink.name = "生"

alc = Alc.new
alc.name = "ビール"
alc.size = "中"
alc.alcohol_content = "5%"

 

上のプログラムの場合だとDrinkクラスをAlcクラスが継承してる感じだね。AlcクラスのスーパークラスがDrinkクラスだね。 見てのとおりなんだけど、AlcクラスはDrinkクラスを継承してるので、Drinkクラスで定義したnameとかname=(text)とかsizeも使えちゃう。便利だよね。なのでalc.nameとかalc.sizeとかDrinkクラスにしか書いてなくてもAlcクラスで使えちゃうっていう!

 

で、スーパークラスとサブクラスのどちらにメソッドを加えるかってことなんだけど、上の場合はアルコール度数はアルコールにしかないので、Alcクラスに加えてるって感じだね。

 

 

Rubyの用意しているクラスの継承関係

 

p Integer.ancestors
p Array.ancestors
p Class.ancestors

 

うえのancestorsメソッドを使うとクラスの継承関係が見れちゃう。こういうの面白いよね。なんかこうワクワクするのは僕だけでしょうか。

 

f:id:kkouji0224:20191103213002p:plain

 

ancestorsメソッドを実行するとこんな感じだね。最終的にBasicObjectにたどり着くね。このBasicObjectって一体何者なんだろう… 今は気にしないでおこう…

 

親子で同名のメソッドを作った時の動作は?

 

class Drink
    def name
        @name
    end
    def name=(text)
        @name = text
    end
    def size
        @size
    end
    def size=(text)
        @size = text
    end
    def full_name
        @name
    end
end

class Alc < Drink
    def alc_content
        @alc_content
    end
    def alc_content=(text)
        @alc_content = text
    end
    def full_name
        "#{@name} #{@alc_content} #{@size}サイズ"
    end
end

alc = Alc.new
alc.name = "生ビール"
alc.size = "中"
alc.alc_content = "5%"
puts alc.full_name

 

サブクラスのAlcクラスのオブジェクトにたいしてfull_nameメソッドを呼び出すと、Alcクラスのfull_nameメソッドが呼び出されるんだね。どんどん遡って最初にあったものが呼び出されるみたいだぜっ。

 

superで親クラスのメソッドを呼び出す

 

class Drink
    def name
        @name
    end
    def name=(text)
        @name = text
    end
    def size
        @size
    end
    def size=(text)
        @size = text
    end
    def full_name
        @name
    end
end

class Alc < Drink
    def alc_content
        @alc_content
    end
    def alc_content=(text)
        @alc_content = text
    end
    def full_name
        super
    end
end

alc = Alc.new
alc.name = "生ビール"
alc.size = "中"
alc.alc_content = "5%"
puts alc.full_name

 

サブクラスAlcクラスのfull_nameメソッドの中にsuperって書いてあげると、親クラスのこの場合Drinkクラスのfull_nameメソッドが呼び出されるんだね。superは親クラスの同名メソッドを呼び出して戻り値を返すんだね。だからこの場合は"生ビール"になるね。

 

クラスの中のメソッド定義の中だけで呼び出せるように制限

 

class Buddhism
    def buddha
        nirvana
    end
    private
    def nirvana
        "真理"
    end
end

buddhism = Buddhism.new
puts buddhism.buddha
puts buddhism.nirvana

 

 はい。また意味のわからない例えプログラムを書いてしまいました… 簡単にいうとbuddha(悟った人)しか真理にってことなんだけども… わかりにくくてすみませんねぇ。思いついたのがこれやねん。見ての通りだ。privateの下に書いてあるnirvanaメソッドはbuddhismってレシーバを指定しての呼び出しができなくなるんだね。で、buddhaメソッドの中からはnirvanaを呼び出して真理ってなる。哲学的だぜ…。

 

レシーバを指定しての呼び出しが禁止されたものをprivateメソッドで、レシーバに続けて書いて呼び出せるものをpublicメソッドっていうんだぜ。

 

上の書き方だと、privateから下はprivateメソッドになっちゃうんだけど、このメソッドだけみたいな書き方もできるんだね。

 

class Buddhism
    def buddha
        nirvana
    end
    private def nirvana
        "真理"
    end
end

 

こんな感じでdefの前にprivateを書いてあげると、そのメソッドだけprivateメソッドにできるんだぜっ。

 

プライベートなクラスメソッド

 

class Buddhism
    private_class_method def self.buddha
        "nirvana"
    end
end

p Buddhism.buddha

 

こんな感じで書いてあげるといいみたい。defの前にprivate_class_methodだね。

 

class Buddhism
    class << self
        private 
        def buddha
            "nirvana"
        end
    end
end

p Buddhism.buddha

 

 class << selfの書き方だとprivateが使えるのでこっちのほうが楽な感じかなぁ。

 

 

ってことでCHAPTER8の振り返りはこれで終わりだね。このCHAPTERが山場かなぁという感じだったのでそれが終わってしまうのは少し寂しい気持ちにもなるけど、Rubyの旅自体は終わらないので、まぁ良しとしましょうかね!!

 

とかいってるけどこの超入門はCHAPTER11まであるので気は抜かずに楽しんでいくぜ。

 

ってことで今日はこの辺でアディオス!

Ruby超入門 2周目 CHAPTER8-6 クラスを使って メソッドを呼び出す まで

f:id:kkouji0224:20191029231558p:plain

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

今日はお休みなので寝まくりました!さらに昼寝までしちゃいました!睡眠最高!!koujiです。おはようございます。

 

ってことで今日も振り返っていくぜー!

 

インスタンスメソッドとクラスメソッド

 

インスタンスメソッド
drink.name
[1234].size
1.even?

レシーバ.メソッドのレシーバのところが
インスンタンス(あるクラスのオブジェクト)

クラスメソッド
Drink.new
Array.new

レシーバがクラス名になってるね。
これはクラスに対して呼び出す。

 

インスタンスメソッドはインスタンス(クラスのオブジェクト)に対して呼び出す!

クラスメソッドはクラスに対して呼び出す!クラスそのものに対して呼び出すんだぜ。

 

インスタンス(オブジェクト)とクラスの違いは…

例えば鈴木家には鈴木1くん鈴木2くん鈴木3さんとか何人もいる。

class 鈴木 なわけですよ。で、鈴木1 = 鈴木.newすると1くんが作られるんだ。この鈴木1くんがインスタンスだ。で、鈴木家がクラスだ。鈴木1くんと鈴木家は違うんだ。 

 

クラスメソッドの定義

 

class Fuck
    def self.fuck
        "ファック!!ファック!!"
    end
end

puts Fuck.fuck

 

定義の仕方は簡単だね。self.をつけてあげるとクラス名.メソッド名で呼び出す。Fuckクラスのfuckメソッドでファック!!ファック!!は自分で書いてて笑った。

 

で、インスタンスメソッドとかクラスメソッドをドキュメントに書くときの記法があるみたい。

 

インスタンスメソッド: クラス名#メソッド名

クラスメソッド: クラス名.メソッド名 もしくは クラス名::メソッド名

 

リファレンスマニュアルとかにもこの記法ででてくるので覚えておいて損はないぜ。

 

同じクラスのクラスメソッドを呼び出す

 

class Fuck
    def self.fuck
        "ファック!!ファック!!"
    end
    def self.mother_fuck
        fuck + "マザーファック!!"
    end
    def self.babylon_fuck
        mother_fuck + "国家権力なんか糞食らえだ!!"
    end
end

puts Fuck.babylon_fuck

 

これは簡単で、インスタンスメソッドのときと同じようにメソッド名だけ書けばOKだファック!!ファック三昧にしてみたぜ。勘違いしてほしくないことが1つあるんだ…いつもわけわかんない感じでプログラム書いてるけど、超入門の中身はこんなにわけわかんない感じで書いてないから安心してほしい… 勘違いする人もなかなか居ないと思うので書かなかったけど念の為だ…

 

ちなみにインスタンスメソッドからクラスメソッドを呼び出すこともできるようだ。

 

class Fuck
    def self.fuck
        "ファック!!ファック!!"
    end
    def self.mother_fuck
        fuck + "マザーファック!!"
    end
    def babylon_fuck
        Fuck.mother_fuck + "国家権力なんか糞食らえだ!!"
    end
end

fuck = Fuck.new
puts fuck.babylon_fuck

 

こんな感じね。インスタンスメソッドのbabylon_fuckの中で、Fuck.mother_fuckって書いてクラスメソッドのself.mother_fuckを呼び出してるね。他の書き方としてself.class.mother_fuckって書き方もできるよ。クラス名.クラスメソッド名かself.class.クラスメソッド名ね。

 

ちなみにクラスメソッドを複数書く場合はこっちのほうが楽だね。

 

class Fuck
    class << self
        def fuck
            "ファック!!ファック!!"
        end
        def mother_fuck
            fuck + "マザーファック!!"
        end
    end
    def babylon_fuck
        Fuck.mother_fuck + "国家権力なんか糞食らえだ!!"
    end
end

fuck = Fuck.new
puts fuck.babylon_fuck

 

これね。class << selefからendまでの中に書いたメソッドがクラスメソッドになる感じだね。その外にあるbabylon_fuckはインスタンスメソッドだね。毎回self書かなくていいので便利だし整理されてる感じがして見やすいよね。

 

ってことでCHAPTER8-6の振り返りでした!

 

長くなっちゃうとわかりにくいので分割していこうかなって思ってます。今日はCHAPTER8-7と8も振り返るつもりでっす。

 

その前にご飯かなぁ。ってことで飯くってくるぜ。

 

アディオス!

 

 

Ruby超入門 2周目 CHAPTER8-5 オブジェクトが作られるときに処理を行う まで

f:id:kkouji0224:20191029231558p:plain

『ゼロからわかる Ruby 超入門 (かんたんIT基礎講座) 』
github.com

 

なんだか今日は調子の良い一日だった。そんな感じ。こんばんはkoujiです。

 

はーい!それじゃ今日も振り返っていきまーっす!!

 

initializeメソッド

 

class Baby
    def initialize
        puts "オギャー!!オギャー!!"
    end
end

Baby.new

 

 initializeってメソッドは特別なメソッドで、これを書いてあげるとオブジェクトが新しく作られた時に自動で呼び出されるんだよ!上のプログラムだとBaby.newで新しくオブジェクトが作られると自動で「オギャー!!オギャー!!」って泣く感じですねぇ…

 

 

initializeメソッドでインスタンス変数の初期値を設定

 

class Alc
    def initialize
        @order = "生中"
    end
    def order
        @order
    end
end

alc = Alc.new
puts alc.order

 

上の場合だとAlc.newで新しいオブジェクトが作成されると、initializeメソッドが自動で呼び出されて@orderに"生中"が代入される感じ。それが初期値になるんだねぇ。orderメソッドを呼ぶと、戻り値が"生中”になってるよーって話だね!やっぱり最初は生中だね。

 

 

initializeメソッドに引数を渡す

 

class Alc
    def initialize(order)
        @order = order
    end
    def order
        @order
    end
end

alc = Alc.new("生中")
puts alc.order

 

はーい。initializeメソッドにも引数渡せますね!initialize(変数)で、この場合はorderだね。で、それを@orderに代入すると。なので上の場合だとAlc.new("生中")でオブジェクト作成時に引数として"生中"を渡してる。で、その生中がinitialize(order)のorderに渡されて、それが@orderに代入されてるって感じだね!なのでputs alc.orderでorderメソッドを呼び出すと戻り値は"生中”になってるよ!

 

class Alc
    def initialize(order)
        @order = order
    end
    def order
        @order
    end
end

alc1 = Alc.new("生中")
alc2 = Alc.new("ハイボール")
alc3 = Alc.new("ウーロンハイ")
puts alc1.order
puts alc2.order
puts alc3.order

 

 上みたいな感じで書くと色々なオブジェクトが作れるね。例えば3人で飲みに行ったとするじゃん。それぞれ最初に注文するものがそれぞれ異なる。生中であったりハイボールであったりウーロンハイであったりね。1くんは生中 2くんはハイボール 3くんはウーロンハイみたいな。そんな感じ!どんな感じやねんって感じだけれど…

 

ってことで、今日はinitializeメソッドでしたぁ〜。しかしこれも便利だねぇ。

 

それにしてもこうやって自分なりに丁寧に復習していくと、それってそういうことだったのねみたいなのもすごく多くて、全然理解してなかったんだなぁと思う反面、なんか少しわかってきたんじゃないの俺?みたいな感じでスローペースだけど面白さが増してくる感じが堪りませんなー。

 

ってことで明日は少し早めに起きないといけないので短いけど今日はこの辺で!

 

アディオス!