20210404_アウトプット(Ruby)

アウトプット画像

今日やったこと

  • ゼロからわかるRuby超入門の続き(7:メソッド〜8:クラスまで)8時間50分

1%の成長

  • ようやくモヤモヤしていたRubyのクラスと向き合えた

新しく学んだこと

メソッド

putsがメソッド内にある時と外にある時の違い

  • メソッド内にある時・・・表示させることもメソッドの仕事の一つとしている。
  • メソッド外にある時・・・処理と表示は別にしており、表示結果を配列や変数にして別のところで使うこともできる。

💡 つまり、外に「表示させる」ことを持ってくると、利用範囲が広がる。


おさらい 戻り値と引数
  • 戻り値とは? 呼び出し元へオブジェクトを返す
  • 引数とは? メソッドへオブジェクトを渡す
  • returnを使わない限り、最後の値が戻り値となる。


引数の便利な機能

キーワード引数

引数が2つ以上になったときは、キーワード引数を検討しよう!

  • キーワード引数のメリットは、大きく2つある。
    (1)引数の渡す順番が異なっていてもシンボルを手がかりに、きちんとオブジェクトが渡されること
    (2)ラベルのようになるので可読性が上がること
def order(item:, size:)
  "#{item}#{size}サイズでください"
end

puts order(item: "ポテト", size: "大盛り")
#=>  ポテトを大盛りサイズでください


デフォルト値の設定
  • 通常はイコールで代入。
  • シンボルの時だけ、キーと値のように書く。
  • デフォルト値を設定すると、ラベルを探しに行くので、引数の順番がメソッドと呼び出し側で異なっていても適切に渡すことが出来るよ。
def order(item = "ハンバーガー")
    "#{item}をください"
end

puts order
#=> ハンバーガーをください
#💡引数を省略するとデフォルト値が適用
def order(item:, size: "普通")
  "#{item}#{size}サイズでください"
end

puts order(item: "ポテト")
#=>  ポテトを普通サイズでください
#💡:sizeを省略したところ、デフォルト値の「普通」が適用となり、引数エラーとならない。


スコープとは?(おさらい)

  • 変数の見ることのできる範囲と、寿命のこと
  • ローカル変数は、メソッド内でしか使うことが出来ない(外から呼び出したり、中のものを外で使えない)

クラスとは?(おさらい)

  • クラスは工場。クラス自身が仕事をすることもあれば、そこから生まれたオブジェクトが仕事をすることもある
  • 新しいクラスを作ることは、新しい特徴をもったキャラクター(プログラムの世界ではオブジェクト)を作ることができる。
  • クラス名はキャメルケースにする。(=定数でもある)
  • Methodsメソッドとは、そのオブジェクトで呼び出せるメソッドを一覧表示することが出来る。レシーバ.methods



クラスを理解しよう!!!

🤔私:「超入門」からやり直したのもクラスに苦手意識があったからなんだ。どのオブジェクトもクラスに属していることはわかっているんだけど、オリジナルのクラスを組み立てるルールがいまいちわからないよ。
🥸先生:具体的に、どのようなルールが分からなかったの?
🤔私:attr_accessorを使ったり使わなかったり、引数渡したはずなのにエラーになってしまったり、いまいちふわっとした理解で書けないんだよね。
🥸先生:超入門本から基礎をしっかり理解しよう。

超入門本からこんなふうに理解した!

前提知識
  • Rubyは全てがオブジェクトであり、何かしらのクラスに所属している。
  • クラス.newで、クラスがインスタンスとして生成される。
  • レシーバとは、メソッドを使って呼び出されるオブジェクトの中身のこと。(例えば、2.even?では2の「整数オブジェクト」がレシーバであるし、["ポメ", "ペキニーズ"].sizeでは、["ポメ", "ペキニーズ"]の「配列オブジェクト」がレシーバである)
今日理解したこと

クラスの中身を作るにあたって、目的が大きく4つあると理解。

目的 内容 ポイント コード例
ただのローカル変数等を呼ぶため そのままの文字列や渡された引数をシンプルに式展開する等 異なる動作は出来ない
インスタンス変数とするため ゲッターやセッター(あるいはattr_accessor)を使い変数を取得・代入する インスタンス毎に異なる動作が出来る/代入されて実行されることで初めてインスタンスとなる/複数のメソッドを跨いで使える
イニシャライズメソッドとするため newメソッドでクラスを生成時に引数で渡すことによって、生成時に持っていて欲しいデータを設定する 引数として届くことが他のメソッドと違う点
クラスメソッドとするため クラス全体を呼び出される中身として表示する クラスが実行するのでオブジェクトを作ることなく呼び出すことが出来る(全体の振る舞い)
ただのローカル変数等を呼ぶため①
class Drink
  def order(name)
    puts "#{name}をください"
  end
end

drink = Drink.new
drink.order("お茶")

#=> お茶をください


インスタンス変数とするため②
class Drink
  def name=(text) #🌟インスタンス変数へ代入している(👈attr_writer :name)
    @name = text
  end
  def name #🌟インスタンス変数を外から取得出来るようにする(👈attr_reader :name)
    @name
  end
end

drink = Drink.new
drink.name= "お茶"  #💡代入している。「drink.name = "お茶"」でも可。
puts drink.name

#=> お茶
  • ゲッターとセッターはattr_accessor :nameと一つにすることが出来る。


イニシャライズメソッドとするため③
class Drink
  def initialize(name)
    @name = name
  end
  def name
    @name
  end
end

drink = Drink.new("牛乳")
puts drink.name

#=> 牛乳
  • newメソッドへ渡す値を帰ると、色々なDrinkオブジェクトを作れる。
  • 外から呼び出すには、参照用のメソッドを上記のように定義するか、アクセサメソッドが必要である。(ようやく繋がった・・・)


クラスメソッドとするため④
class Cafe
  def self.welcome
    "いらっしゃいませ!"
  end
end

puts Cafe.welcome      🌟呼び出す際はクラス.メソッド名だけでOK

#=> いらっしゃいませ!

あるいは

class Cafe
   class << self
      def welcome
        "いらっしゃいませ!"
      end
   end
end

puts Cafe.welcome

#=> いらっしゃいませ!
  • 下の段は、複数のクラスメソッドを書くときに便利(ネストが一つ深くなる)またちょっと先の話になるけれどクラスメソッドをprivateメソッドにしたいときはclass << selfの構文を使うよ。
  • インスタンスメソッドからクラスメソッドを呼ぶことも出来る(self.class.クラスメソッドまたはクラス.クラスメソッド)逆に、クラスメソッドからインスタンスメソッドを呼び出すことは出来ないので注意。(どのインスタンスメソッドであってもクラスメソッドは共通なので呼び出せるが、インスタンスメソッドはレシーバがその都度異なるため)
  • クラス.newnewはクラスメソッドだよ!!!



そのほか便利なメソッド

メソッド 読み方 内容
instance_variablesメソッド インスタンスバリアブル インスタンス変数の変数名一覧を取得するメソッド
ancestorsメソッド アンセスター(祖先)メソッド 継承関係上の祖先をたどることが出来るメソッド



継承のルール

  • 継承は<一つ!(つい、クラスメソッドの2つとごっちゃになる)
  • 継承の目的は、「似たメソッドを何度も書くの面倒」なので、それらを引き継ぎつつ、「一部変えたい」という時に使える。
  • ”「子クラス」は「親クラス」の一種である”と声に出しても違和感がない時は適切な継承と言える。
  • 親子のクラス🐓🐤で同名のメソッドがある時は、「最初に該当したメソッド🐤」を呼び出す
  • もし「最初に該当したメソッド🐤」ではなく、親クラスの同名メソッドを呼び出したい時は「🐓super🐓」と書く。
  • 同名の「子クラス」と「親クラス」のインスタンス変数や、privateメソッドは、継承がきっかけでオーバーライドを引き起こし、バグを起こす原因にもなりうるので注意。



制限のルール

🤔私:それぞれのメソッドのルールを上手く使えば外からも中からも呼び出せるようになったね!
🥸先生:あえて「レシーバを指定して呼び出すことができないインスタンスメソッド」としてprivateメソッドがあるよ。
🤔私:出来ること減らしてしまうので、無意味では?どうしてプライベートにするの?
🥸先生:privateメソッドにする=外から呼び出さないようにすると明示することで「このクラスとオブジェクトではAメソッドではなくBメソッドを使ってくださいね」と設計上の意図を他のプログラマーに伝える大事な役割を担っているよ。



感想

  • 本当は、SPIや、PHPの基礎なども学びたかったがそこまで行けなかった💦
  • でも、ずっとモヤモヤしていて理解したかったRubyのクラスについて理解することができた。
  • 一つの型をしっかり理解すれば、他の言語の基礎も差分を捉えながら出来ると信じてRubyを今は頑張っている。
  • 今日は午前中、カフェに行ってみた。集中できたのでよかったなあ。前、銭神さんがおっしゃっていた動く椅子だと動くことが気になってしまうことにすごく共感(笑)最近は動かない椅子にハマっている。
  • 大きいモニターを導入!!mac小さかったから画面見やすくなって嬉しい!!!

20210402・03_アウトプット(Ruby)

アウトプット画像

今日やったこと

  • HTMLの理解を深める 50分

  • ゼロからわかるRuby超入門の続き(6)3時間40分

  • Laravelのアプリ 1時間(mysql接続ができておらず、migrateがうまくいかなかった もう少し調べよう)

1%の成長

  • ブロック変数について、ハッシュと配列でごっちゃになっていた部分が整理できた。ハッシュの時は、原則キーと値の2つを渡す。each_keyeach_valueなどのメソッドを使う時だけ、そのうちの一部を指定しているので1つとなる。

  • 配列の時は、配列の直後にメソッドをつけることが出来たが、ハッシュの場合には代入した変数に対してdeletemergeメソッドを行うことを理解。

新しく学んだこと

ハッシュ全体のこと

  • ハッシュをpメソッドで出力する際はハッシュを丸かっこで囲わないと、文法の解釈が曖昧となりエラーとなること。

  • シンボルへ変換するときはto_symメソッドがあること。

  • キーとシンボルを同じ意味に捉えていた。しかし、違った。
    🟢「キーとバリュー」は「見出しと内容」という概念のことを指す。
    🟢シンボルは「キー」を表現する方法の一つ。ハッシュロケットを使う場合には、シンボル以外(文字列など)をキーにすることが出来る。

  • ハッシュに対して、キーを指定して探そうとした時、値がない場合はnilを返すが、デフォルトを設定することもできる。

menu = { coffe: 300, caffe_latte: 400}
menu.default = "その値はないよ"
p menu[:tea]

#=> "その値はないよ"



mergeメソッド

  • merge メソッドを使い、2つのハッシュを1つにまとめることができる。
coffee_menu = { coffee: 300, caffe_latte: 400 }
tea_menu = { tea: 300, tea_latte: 400 }
menu = coffee_menu.merge(tea_menu)
p menu

#=> {:coffee=>300, :caffe_latte=>400, :tea=>300, :tea_latte=>400}
  • 逆でもOK(そうすると、teaからの順になった)
  • menuではなく、coffee_menutea_menuを代入後の変数にしたら、NameErrorになった💡個別で値の代入をする時は書き換え(上書き)が出来るけれど、「ハッシュ自体を定義した変数」と「マージした後の変数」という同義にならない場合はちゃんとエラーになるんだと勉強になった。
  • ハッシュに直接繋いでもNameErrorになった({ coffee: 300, caffe_latte: 400 }.merge(tea_menu)


deleteメソッド

  • キーと値する時はdeleteメソッドを使う。ハッシュ.delete(キー)
menu = { book: 500, note:100 }
menu.delete(:note)
p menu

#=> {:book=>500}


eachメソッド

  • ハッシュでeachメソッドをする時は、ブロック変数としてkeyとvalueの2つを渡す。

  • ブロック変数名はkeyとvalue出なくても可能。

menu = { coffee: 300, tea: 400 }
menu.each do |key, value|
  p "#{key}#{value}円です"
end

#=> 
"coffeeは300円です"
"teaは400円です"


  • 🤔keyだけ、あるいはvalueだけ表示させたい時はどうするの?
  • 🥸each _keyメソッドやeach_valueを使おう
メソッド ブロック変数の数 内容
each 2つ(key・value キーと値を表示
each _key​ 1つ(key) キーのみ表示
each_value 1つ(value 値のみ表示

感想

  • 午前中に、オンラインスクールの時の仲間と近況報告。息抜きになった😌仲間がわからないと言っていたAWSにおけるエンジンエックスの役割を説明したら、理解につながったようで嬉しかった。
  • 最近、メリハリを大事にするよう心掛けている。ついプログラミング以外の時に、心のどこかでプログラミングのことを考える気持ちが抜けないでいた。自分のメンタル的にも関わる相手にとっても良くないなーと感じていたものの、ついつい心配性で考えてしまう癖がある。プログラミングもそうでないことも1つ1つ楽しみながら気持ちを切り替えよう!

20210401_アウトプット(Ruby)

アウトプット画像

今日やったこと

  • ゼロからわかるRuby超入門の続き(5の練習問題)40分

1%の成長

  • リファレンスをみながらメソッドを探すことに少しずつ慣れてきた
  • また練習問題解くときに、vimを使うようにしていて、ファイル作成や行のコピーに慣れてきた
  • メソッドの中でもよく使うsplitやmap、joinメソッドが理解できるようになった


新しい発見

  • 「配列の中身の合計」とみた時に+=で順番に足す構文を想像してしまうが、sumメソッドなら一行で記述できる

  • %Wと%wの違いは、%W(式展開あり)と%w(なし)の違い。””を使わなくて済むのでスッキリする

  • split ⇄ joinである

p ["100", "50", "300"].join(",")
#=> "100,50,300"

p "100,50,300".split(",")
#=> ["100", "50", "300"]
復習
メソッド 意味
uniq 重複なくす
clear 配列の中身を空にする
sample ランダムに配列の中から1つの要素を出力する
map 中身に同じ処理をする(新しい配列を得ることが目的!)
downcase 全て小文字にする


感想

  • 今日は勉強時間をあまり取ることができなかった。しかし15分以上のマイルールは達成できた。(自分を責めずに、休む自分も大事にしよう💦😊)
  • 配列の展開はよく使うと思うので、繰り返し復習したい。
  • やりたいことが沢山あって優先順位に迷うけれど、今やっているRuby超入門の本をまずやり切ろう。
  • あっという間に新年度。昨日と今日、同じ一週間なのに、人事異動で人がガラッと変わると大きく雰囲気が変わる。若干緊張するけどフレッシュな気持ちになるのでこの雰囲気は好きだなあ。天気も暖かくなってきたし、晴れやかでいい。🌸
  • 新年度明けの忙しさと、勉強の両立、乗り切ろう!!!

20210331_アウトプット(mysqlエラー→解決できた😍)

アプトプット画像

今日やったこと

  • mysqlのエラーと格闘 →解決🎉(4時間)

1%の成長

  • エラーと向き合えた
  • mysqlの理解ちょっと進んだ
  • バージョンアップって学ぶこといっぱいある(上手くいったと思っていても、後で地雷を踏んで爆発することがある💣)


新しい発見

ログの確認

この記事を見て、ログも合わせて確認しようと思った。

dev.mysql.com

ログから読み取ったこととしては、「REDOログはMySQL5.7.9以前に作成されたもの。Data Dictionaryの初期化に失敗したよ」

% tail -f /usr/local/var/mysql/noMacBook-Air.local.err
2021-03-30T22:00:27.181813Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /usr/local/var/mysql/ is case insensitive
2021-03-30T22:00:27.195807Z 1 [System] [MY-011012] [Server] Starting upgrade of data directory.
2021-03-30T22:00:27.195917Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2021-03-30T22:00:27.284951Z 1 [ERROR] [MY-013090] [InnoDB] Unsupported redo log format (0). The redo log was created before MySQL 5.7.9 👈👀❗️
2021-03-30T22:00:27.285128Z 1 [ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error Generic error.
2021-03-30T22:00:27.286229Z 1 [ERROR] [MY-011013] [Server] Failed to initialize DD Storage Engine.
2021-03-30T22:00:27.286786Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed. 👈👀❗️
2021-03-30T22:00:27.287122Z 0 [ERROR] [MY-010119] [Server] Aborting
2021-03-30T22:00:27.287726Z 0 [System] [MY-010910] [Server] /usr/local/opt/mysql/bin/mysqld: Shutdown complete (mysqld 8.0.23)  Homebrew.
2021-03-30T22:00:27.6NZ mysqld_safe mysqld from pid file /usr/local/var/mysql/efuERIKAnoMacBook-Air.local.pid ended
2021-03-30T22:00:37.6NZ mysqld_safe Logging to '/usr/local/var/mysql/efuERIKAnoMacBook-Air.local.err'.
2021-03-30T22:00:37.6NZ mysqld_safe Starting mysqld daemon with databases from /usr/local/var/mysql
2021-03-30T22:00:37.824064Z 0 [System] [MY-010116] [Server] /usr/local/opt/mysql/bin/mysqld (mysqld 8.0.23) starting as process 7372
REDOログって何?
  • 更新履歴のファイルだよ(データベースへの変更があるたびに記録)。ただし上限があるのでいっぱいになると上書きし始める。
  • 上書きすると、そこからログを使って復旧できなくなるため、REDOログが、いっぱいになる前にアーカイブ ログが作成される。
  • アーカイブ ログは、勝手に消えることはないので定期的に削除しないと容量がいっぱいになってしまう。アーカイブ ログについて通常は自動で削除する設定をする。
調べたところから立てた仮説

昨日調べたことも含めて、今回エラーが発生した経緯は、以下の通りでは?と仮説を立て始めた。

(1)macをBigSurにし、RubyRailsをアップデートした時、mysqlは5.6をインストールしてサーバー起動。
(2)brew upgradeにより、てHomebrewでインスールしたパッケージたちが全てバージョンアップ(mysqlも5.6から8.0へ)
(3)macの電源を切った。
(4)ターミナルを再起動した際、mysql8.0が起動。今まで作ったアプリたちはmysql5.6だったので「mysql5.6のログ残っているよ、8.0でこのまま立ち上げできないよ」とエラーに陥った。

と考えた。
当初は「/tmp/mysql.sockがない」ことが原因だと思っていたが、ディレクトリはmysql8.0において存在している。 そのことから、「意図せずmysql8.0の起動になっている部分」を「mysql5.6で起動」すれば上手くいくのではないか?と思った。

↓↓この記事が参考になった。

s8a.jp

直った!!!!!

覚書

  • バージョン指定して起動したら直った。😻❗️💗
noMacBook-Air ~ % /usr/local/opt/mysql@5.6/bin/mysql.server start
Starting MySQL
.. SUCCESS! 
noMacBook-Air action_app % mysql -v
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.6.51 Homebrew

Copyright (c) 2000, 2021, Oracle and/or its affiliates.
(省略)
  • ちなみに、もう一度落として、スタートしたら同じエラーでた(エラーを再現できた!!!)原因はこれだったのか💡嬉しかった〜!!!
  • よく理解しないまま、Qiitaの記事を見て、mysql5.6のファイル等を削除しなくて良かったと感じた😭✨🙏笑
noMacBook-Air ~ % /usr/local/opt/mysql@5.6/bin/mysql.server stop
Shutting down MySQL
. SUCCESS! 
noMacBook-Air ~ % sudo mysql.server start
Password:
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/efuERIKAnoMacBook-Air.local.pid).


感想

  • 時間はかかったけれど、解決できて嬉しかった〜!
  • この感覚は、オリアプを作っていた頃の気持ちを思い出した(笑)
  • プログラミングって「背景や意図など新しい知識を知れた時の面白さ」「エラーに苦しむけど調べまくってブラウザに反映した時(形にできた時)の嬉しさ」2種類あると最近感じている。
  • 最初は「Railsなどの続きやりたいし、変なところでエラー出ないでー!!」と内心思ったが、結果として面白かったから良かった。
  • dumpコマンドで、バックアップを取ることを知った。結果として、mysql5.6のままなので、時間ある時に5.7から8.0にチャレンジしてみよう😊!!

20210330_アウトプット(mysqlエラーと格闘)

アプトプット画像

今日やったこと

  • mysqlのエラーと格闘(3時間45分) →未解決



新しい発見

上記エラーについて調べたり、感じたこと
  • mysql5.6使っていたが、mysql5.7のあとは、8.0と一気にメジャーアップデートされていたことを知る。

  • mysql8.0はシークエルプロ使えないみたい。ただし、それに変わるアプリもあることを知る。

qiita.com

  • brew updateしたことにより、Mysqlのバージョンも最新版へ意図せずアップグレードしていたことが原因の様子。

  • 解決法を探すとバージョン5.6や5.7にダウングレードする方法が出てくる。

  • はじめはそれを試みていたが、ふとそれは「エラーを解消」だけが目的であり、そもそも「最新版の8.0」によるメリットは何か?(どんな影響があるのか)、もしそちらの方がよければ8.0を使う方法を模索した方がいいのではないかとも思い始めた。そういえば一次情報ちゃんと調べてなかったと思い始めた。


mysql8.0のメリット
  • SQLを勉強していた時に、それを扱うリレーショナルベース管理システムごとの癖が結構違うと感じていたが、mysql8.0では、それらのメソッドが便利になったり記述が簡略化されるようになったと理解。

  • 全てを理解は出来なかったが、ハードディスクの大容量化などによりログの出力する方がデフォルトに変わったり、クエリキャッシュと呼ばれるデータを抽出した時に一時的に残さないモードにしておかないと新しいバージョンでは起動しなくなったり、ユーザー認証に変更があることを知った。

eh-career.com

一次情報見てみよう
  • バージョンアップする前に確認すること(今回の場合、意図せずバージョンアップしちゃったけど互換性を確認するため)

  • Rubyの時に学んだようにちびちびバージョンアップした方がいい。

  • バックアップを取る必要もある。

dev.mysql.com

  • mysqlのアップグレードに伴う予備チェックをするコマンド
mysqlcheck -u root -p --all-databases --check-upgrade

=>mysqlcheck: Got error: 2002: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38) when trying to connect
  • そもそもなぜ、/tmp/mysql.sockに接続しようとしているの?

掘り下げ1:cofig>database.ymlにおいて指定していた。

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock   👈👀❗️

掘り下げ2: リファレンスにもこの場所がデフォルトですって書いてあった。(知らなかった。)

サーバーがローカルクライアントと通信するために使用する UNIX ソケットファイルのデフォルトの場所は、/tmp/mysql.sock です

dev.mysql.com

  • mysqlのWebページ見づらい・・と思っていたが、右上のタブでバージョン切り替えてリファレンス読めることがここら辺でだんだん分かってきた。
バージョンを確認するコマンド(エラー内容がより詳しく出た)

起動しているか存在しているか確認して!

noMacBook-Air ~ % mysqladmin version
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)'
Check that mysqld is running and that the socket: '/tmp/mysql.sock' exists!

この2つの記事が解決の糸口になりそう😣

ソケットファイルの指定方法

MySQL :: MySQL 8.0 Reference Manual :: B.3.3.6 How to Protect or Change the MySQL Unix Socket File

今回のエラー原因では?

MySQL :: MySQL 8.0 Reference Manual :: B.3.2.2 Can't connect to [local] MySQL server



感想

  • エラー解決に必死になっていたけれど「1次情報そういえばちゃんとみてない」と視点を持てたのはよかった。
  • なぜならばRubyRailsなども、サポートされなくなるからバージョンアップするのに、必死になって「グレードダウン」する方法を調べているのでは?と思えてきたため。
  • 上手くいくかわからないけれど、会社で失敗するより個人で失敗する方がいいので、ターミナルのちょっと不安なコマンドも、意味を調べながら、チャレンジしてみようと思っている💦(エラー解決しますように・・・)
  • 調べたり、「どういう意味?」で今日の勉強終わってしまったが、向き合えたからよしとしよう。
  • バージョン8.0で、あとデフォルトのコネクト先を設定すればいける気がするんだけど違うのかな?そもそも設定どうするんだ?
  • しっかり寝てまた明日向き合ってみよう。
  • 自分の大事に思っている考えと技術力が高い方の思考が似ているととても嬉しい。少しでも近づけるように技術力アップ頑張ろうと励みになる。

20210329_アウトプット(Ruby)

アプトプット画像

1%の成長

  • ゼロからわかるRuby超入門(3時間半)


新しい発見

sizeメソッドとlengthメソッドはエイリアスメソッド(別名メソッド)

私🤔:配列の要素数ってどうやって数えるの?
先生🥸:sizeメソッドlengthメソッドで数えることができるよ。
私🤔:異なるメソッド名でも、同じ実装になるんだね。
先生🥸:うん、それらをエイリアスメソッド(別名メソッド)といい、文脈や好みで使い分けるよ。 同じ実装でも速度が違う場合があるので、速さを一つの基準にしてもいいかもしれないね。

puts [2, 4, 6].size       #=>3
puts [2, 4, 6].length   #=>3
require 'benchmark'

Benchmark.bm 10 do |r|
  r.report "size" do
  end
  r.report "length" do
  end
end

# 結果

                 user     system      total        real
size         0.000011   0.000010   0.000021 (  0.000007)
length       0.000003   0.000001   0.000004 (  0.000003)


配列の全要素の合計を得るにはsumメソッド/平均を出すにはそれをsizeメソッドかlengthメソッドで割る
  • 注意としては、合計値を使って平均を出すときに、デフォルトは整数になっているのでto_f(小数)に変換するメソッドを使わないと正しい値がでない場合があること。
a = [1, 2, 2]
puts a.sum / a.size       #=> 1
puts a.sum.to_f / a.size  #=> 1.6666666666666667


uniqとuniq!の違いは何?/新しい配列を作り出すか・配列そのものを変更(破壊的)するか
  • 末尾に!がつく/つかないメソッドがある。
  • !がつくと、オブジェクトを破壊的に変更し、!がつかないと新しい配列を作って返すものが多い。
ブロックを渡せるメソッド
p [1, 3, 2, "2", "3"].uniq                # => [1, 3, 2, "2", "3"]
p [1, 3, 2, "2", "3"].uniq { |n| n.to_s } # => [1, 3, 2]
  • 2つめはブロックで一つずつ、配列の中身を全て文字列にしてから重複を取り除いている(これをto_iにして全て整数にしてから重複を取り除くでも結果は同じ)


配列をランダムに操作

メソッド 内容
sample 配列の中からランダムで一つ選ぶ
shuffle 配列の中身をランダムに並び替える


配列の並びかえ

私🤔:そのまま、reverseメソッドを使う時と、sortメソッド+reverseメソッドの違いは何?
先生🥸:配列の中身を「そのまま逆」にするか、中身が大きい順/小さい順、アルファベット順(かつ大文字優先)など並び替えたものをリバースするかの違いだよ。

ary1 = [ "d", "a", "e", "c", "A" ].sort.reverse  #=> ["e", "d", "c", "a", "A"]
ary2 = [1, 2, 4, 5, 6, 4, 0].sort.reverse           #=> [6, 5, 4, 4, 2, 1, 0]
  • 注意点としては、「文字列」の数字をソートした時は、正しく大きい順/小さい順にならないので、uniqメソッドで学んだ時のようなブロックにして(全てto_iメソッドで変換して)並び替えるよ。また大小の比較をしながら並び替えるため、ブロック引数として2つ渡す必要があるよ。
p ary2.sort{|a, b| a.to_i <=> b.to_i }  #=> ["7", "8", "9", "10", "11"] (ブロックを使って数字としてソート)

配列の「中身」をくっつけるjoinメソッド

  • 配列の中身をくっつける
  • くっつける時に、要素間に指定の文字を入れて欲しい というような場合はjoinメソッドが便利!
puts ["りんご", "みかん", "いちご"].join("")   #=>りんごとみかんといちご
puts ["りんご"].join("")   #=>りんご
  • とても便利だと感じたのは、要素が一つの時には「連結していない」と判断してつかないようになること。
文字列を分割して、配列にするsplitメソッド
  • 文字列と文字列の間は「半角スペース」分空いている、「”と”」で繋がっているなど、法則性があるときにその文字列で区切って配列にしてくれるメソッド。
puts "りんご みかん バナナ".split(" ")
りんご
みかん
バナナ
puts "りんごとみかんとバナナ".split("")
りんご
みかん
バナナ
配列の中身に対して、同じように〇〇したい時に使えるmapメソッド
  • 配列の各要素に対して同じ処理をして、変換後の要素を「新しい要素」として作り出すメソッド。

私🤔:eachメソッドと何が違うの?
先生🥸:eachメソッドは、各要素に対してブロックで処理を行うことが目的で、mapメソッドは各要素を変換した新しい配列を作ることは目的になるよ。

puts ["", "", ""].map do |x|
    "{x}色"
end

#=> 
赤色
白色
黒色
result = ["abc", "123"].map { |text| text.reverse }
p result

#=> ["cba", "321"]
result = ["abc", "123"].map(&:reverse)
p result

#=> ["cba", "321"]
  • また各要素に対する処理で、あるメソッドで呼び出す(処理を施す)場合については、シンボルである&:メソッド名で表現できる。
  • ただし、これが使えるのが①ブロック引数が一つだけ②引数がないこと③メソッドを1回呼び出したら終わり、という条件が揃った時。

🤔私:&:メソッド名ってどういう状態?
🥸先生:&と、:メソッド名の組み合わせ。&はprocオブジェクト(ブロックをオブジェクト化するクラス)の一つでブロック処理を一つのカタマリにしている。:メソッド名はシンボル(オブジェクトの種類の一つ。)にしている状態だよ。

docs.ruby-lang.org

docs.ruby-lang.org



感想

  • split、mapについて、ネットでふわっとした概念で理解していたので、役割がきちんと理解できて嬉しかった。
  • 今日はSPI勉強できなかったけれどRubyについて、引き出しが増えたのでよしとしよう。
  • どうしても眠いので今日はもう寝る。

20210328_アウトプット(Ruby)

アプトプット画像

1%の成長(昨日の自分の知識より1%成長する)

  • Wantedlyの「将来やってみたいこと」「やったこと」を追記・投稿(1時間)

  • ゼロから分かるRuby入門(チャプター1から4まで)(4時間)

  • paizaのスキルチェック(1時間)

  • SPI(1時間30分)

新しい発見

ゼロからわかるRuby入門

簡単なプログラムをかく
  • pメソッドはデバッグの道具として使う。(プログラムの機能として意図して表示するときはputs)

🤔(どうして?)
pメソッドが唯一、戻り値が「引数のオブジェクト」になるからだよ。(putsメソッドは改行ありでnil、printメソッドは改行なしでnilとなる。nilじゃどこが間違えているのか分からない。)

  • エラーメッセージの時に、コロン(:)で区切られた数字は、プログラムの何行目でエラーが起きたのかを教えてくれる。
条件分岐
  • 慣習的に末尾に?がつくメソッドはtruefalseで返すことが多い。even?(偶数か?)、odd?(奇数か?)

  • 後置ifのときはend不要。

  • elsifは複数書けるが、書きすぎると読みづらくなる。そんなときは、&&||caseを検討しよう。

内容 選択肢がこんな時に使う
if 二択
case 三択以上
  • 「一つ選ぶ」はcase 変数と定義。caseを書かないときは、whenの後に条件をかく。

  • case文のとき、複数に合致するものがない時の選択肢としてelse。

繰り返し
  • 慣習的に、ブロックを複数行で書くときは、do ~ end、一行で書くときは、{ ~ }

  • 「条件付き繰り返し」が`while

case 変数
when 候補1
  変数の値が候補1の時と等しい時の処理(複数行書くことも可能)
when 候補2
  変数の値が候補2の時と等しい時の処理(複数行書くことも可能)
end

変数を書かずに、「候補1」や「候補2」に条件を書くことも可能。(wallet >= 500)

while 条件
  条件を満たしている間、繰り返し実行する処理
end
  • ブロックの時のようにdoは不要。

  • 「繰り返し実行する処理」の戻り値を元に「条件」を判定する。なので条件が「変数 < 2」だった時、1週目の時の戻り値は「1」なので、「2」まで実行されることがスッキリ。

配列

- 配列の中身のオブジェクトクラスはバラバラでも可能(例 文字列、整数、小数点が入った配列)

  • 変数を使わずにメソッドを呼び出すことも可能
p ["牛乳", "お茶"].first  #=> "牛乳"
要素の追加 メソッド
末尾に追加① push
末尾に追加② <<
先頭に追加 unshift
要素の削除 メソッド
末尾の要素を1つ削除 pop
先頭の要素を1つ削除 shift
  • popメソッドとshiftメソッドは、削除した要素を返す。

  • |はパイプと読む。

感想・振り返り

  • 「全部頑張らないと」のように、変に自分を追い詰める癖を改善したいので、1%の成長項目を追加してみた。「1%進めよう」という気持ちでやってみたら、「変な焦り」に囚われることなく、一つずつ出来て良かった。
  • 昨日、ルビィのぼうけんを読んでいて、最後の鳥井さんのコメントにあった「よく観察すること」「その中からパターンを見つけること」「小さいことから始めて大きくしていくこと」に励まされた。あとビットの世界の絵がとても可愛い。素敵だ。
  • Rubyを書くことがまだまだ下手な自分を受け入れよう。Ruby入門の本から始めてみて着実に成長しよう。
  • 今思うとここ一週間を振り返って「自分はエンジニアに向いていないのかもしれない」「なんでこんなにコード書けないんだろう」と「自分ができる感覚が持てない」ことが一番辛かった。
  • 「出来る気が持てない」と、やる気やモチベーションが大きく低下することを実感した。
  • 「出来る実感」を持つにはどうしたらいいか。今何が出来る?小さく成長するにはどうしたらいい?
  • なぜ書けないのか?①何より自信がない。②問題を細かく「順序進行」「繰り返し」「条件分岐」に分ける力が弱いのでは。③型がふわっとした理解。特に、メソッドへの引数の渡し方・クラス・ブロック引数・モジュールあたりの知識の理解がまだまだ。
  • 嬉しかったのは、基礎を4までだけど、行なってからpaizaを解いてみたら解けるようになったこと。楽しくなってきた。ちょっとずつ自信つけていこう。