nesheep5's blog

子持ちWebエンジニアのブログ。プログラミング・仕事効率化・健康・子育て etc...

【Ruby入門】構造化データにStructクラスを利用する

Ruby門中です。今日はStructクラスについて調べました。

Structクラスとは

一言で言うと、クラスより簡単に構造体を作成する仕組みです。
docs.ruby-lang.org

Structクラスの特徴

定義が簡単

Struct.newで引数に渡したシンボルに対応するメンバとアクセサメソッドを持つクラスを生成します。

  # 気温情報を持つ構造化データ
  Temperature = Struct.new(:date, :high, :low)
  temp = Temperature.new('2018/01/01', 8.0, 0.5)
  temp.high # => 8.0

ブロックでメソッドも定義可能

ブロックを利用することでメソッドを定義することも可能です。

  Temperature = Struct.new(:date, :high, :low) do
    def mean
      (high + low) / 2.0
    end
  end

Structクラスの使いどころ

構造化データを用意する際、Hash、Class、Structあたりが選択肢となります。
以下のような時にStructクラスを利用すると良さそうです。

  • ちょっとした構造化データが必要だが、クラス作るほどではない
    • 利用箇所が限定的
    • その構造化データが今後拡張される想定がない(継承、ミックスインなどしない)
  • Hashのように、メンバが動的に変更されたくない
    • 動的に変更する構造化データが欲しい場合、OpenStructクラスも用意されている

HashとStructの比較サンプルソース

以下、Hashを利用した場合とStructを利用した場合の比較サンプルソースです。

require 'csv'

# --- Hashを利用した年間気温クラス
class AnnualWeatherWithHash
  def initialize(file_name)
    @readings = []
    CSV.foreach(file_name, headers: true) do |row|
      @readings << {
        date: Date.parse(row[2]),
        high: row[10].to_f,
        low: row[11].to_f,
      }
    end
  end

  # 平均気温
  def mean
    return 0.0 if @readings.size.zero?
    total = @readings.reduce(0.0) do |sum, reading|
      sum + (reading[:high] + reading[:low]) / 2.0
    end
    total / @readings.size.to_f
  end
end

# --- Structを利用した年間気温クラス
class AnnualWeatherWithStruct
   # Structを作成しReading定数に保持
  Reading = Struct.new(:date, :high, :low) do
    def mean  # ブロックでメソッド定義することも可能
      (high + low) /2.0
    end
  end

  def initialize(file_name)
    @readings = []
    CSV.foreach(file_name, headers: true) do |row|
      # Reading定数をクラスのように利用することができる
      @readings << Reading.new(Date.parse(row[2]), row[10].to_f, row[11].to_f)
    end
  end

  # 平均気温
  def mean
    return 0.0 if @readings.size.zero?
    total = @readings.reduce(0.0) { |sum, reading| sum + reading.mean }
    total / @readings.size.to_f
  end
end

参考

  • Effective Ruby (項目10: 構造化データにはHashではなくStructを使おう)

「プロを目指す人のためのRuby入門」は他言語経験者に最適の本

「プロを目指す人のためのRuby入門」を読んだ

仕事でRubyを使うことになったので、本腰を入れて勉強しようと「プロを目指す人のためのRuby入門」(通称:チェリー本)を購入しました。
昔個人的にRubyを勉強していたころ、著者である伊藤淳一さんの技術ブログをよく参考にしていたのでこれは!と予約して購入しました。
通勤や昼休みなどに毎日少しずつ読み進めていきました。
とても良い書籍だったのでおすすめポイントなど紹介します。

おすすめポイント

エンジニアとしてのこだわりがたくさん詰まっている書籍だと感じました。
著者自らが語るこだわりの記事も参考になります。 blog.jnito.com

進行が分かりやすい

最初から順に読み進めてきちんと理解できるように章構成されています。

  • 章初で例題の仕様を提示
  • 例題に必要な知識を説明
  • 知識が揃ったところで例題に着手(基本的にTDDで行う)
  • 必要に応じリファクタリング
  • 発展系の高度なトピックを説明

という進行です。
ご本人のこだわりポイントとして挙げているように、章中に例題があるのが特徴的です。
例題が軸となって学習が進められるので、覚えるべきことが明確になって進めやすかったです。
また語り口が柔らかく、ペアプログラミングをやっているような感覚になります。

情報の粒度・質が高い

曖昧過ぎず、細か過ぎず、他言語でプログラミングを経験している人にとってちょうど良い粒度の内容だと思います。
リファレンス見れば分かるようなことは少なめで、かわりに実務上引っかかりやすいTipsなどが詳しく書いてあり、現場のエンジニアの知見がたくさん詰まった有用な情報ばかりです。

また、本書に収録できなかった技術記事をQiitaのアドベントカレンダーとして公開してくれています。
qiita.com

例題が個性的

proc/yieldの例題として、ワードシンセサイザーなるものが登場したのですが、さながらギターのコンパクトエフェクターのようで、自分も学生の頃弾いていたので思わずニヤリとしました。笑
自分の趣味を織り交ぜて、さらっとOOPで表現するところが素敵なエンジニアだなと思いました。
業務でJavaを使っているのですが、ラムダ式の利用シーンが分からない人たちにこの例題で説明してあげたら良いかも、と思いました。

紙質にこだわっている

写経に便利なよう、本を開いたままにできる紙を使用しています。
これにはめちゃめちゃ感動しました!全ての技術書がこの紙質になればいいと思います。笑

対象読者、オススメの読み方

他言語でプログラミングをひと通り経験している人に向けの書籍です。
プログラミング自体が初めての人にとっては少し難しいかもしれません。

個人的には

の順で進めると最短でRailsエンジニアになれるのでは、と思いました。

その後、

で深く勉強していくのが良さそうかなと感じています。(※よい勉強の仕方あれば教えてください)

参考

改訂2版 パーフェクトRuby
Rubyサポーターズ
技術評論社
売り上げランキング: 103,291
Effective Ruby
Effective Ruby
posted with amazlet at 18.02.14
Peter J. Jones
翔泳社
売り上げランキング: 264,608
メタプログラミングRuby 第2版
Paolo Perrotta
オライリージャパン
売り上げランキング: 200,922

【Ruby入門】superの振る舞いについて

最近Rubyを勉強しています。
Effective Rubyでsuperの振る舞いについて勉強していたところ、サンプルソースが少しわかりにくかったので自分なりに噛み砕いてみました。

1.カッコの有無による振る舞いの違い

  • オーバーライドするメソッドに引数を渡したくない場合は、 super()とする 。
    superではないことに注意。

サンプルソース

class SuperClass
  def m1(x=0, y=0)
    puts "x=#{x}, y=#{y}"
  end
end

class SubClass < SuperClass
  def m1(x, y)
    super(1, 2) # => x=1, y=2
    super(x, y) # => x=a, y=b
    super x, y  # => x=a, y=b
    super       # => x=a, y=b
    super()     # => x=0, y=0 (引数なしで呼び出し)
  end
end

subclass = SubClass.new
subclass.m1('a', 'b')

2.superに対応するメソッドの探索順序

  • スーパークラスのメソッド、moduleのメソッドを呼び出す
  • <クラス>.ancestorsメソッドで返却される、親クラスの配列順にメソッド探索を行う

サンプルソース

class SuperClass
  def m
    puts "SuperClass"
  end
end

module ModuleA
  def m
    puts "ModuleA"
  end
end

module ModuleB
  def m
    puts "ModuleB"
  end
end

# 検証
class SubClass < SuperClass
  def m
    super #=> SuperClass
  end
end

class IncludeModule
  include ModuleA

  def m
    super #=> ModuleA
  end
end

class IncAndSub < SuperClass
  include ModuleA
  include ModuleB
  def m
    p IncAndSub.ancestors #=> [IncAndSub, ModuleB, ModuleA, SuperClass, Object, PP::ObjectMixin, Kernel, BasicObject]
    super #=> ModuleB (ancestorsの結果の順に遡ってメソッドを探す)
  end
end

SubClass.new.m
IncludeModule.new.m
IncAndSub.new.m

3.コンストラクタでのsuperの振る舞い

  • Javaと違い、コンストラクタ(initializeメソッド)は暗黙的に親クラスのコンストラクタを呼ぶわけではない
  • 親クラスのコンストラクタを呼びたい場合は、initializeメソッド明示的にsuperを記述する必要がある

サンプルソース

class Parent
  attr_accessor :name
  def initialize
    @name = 'Howord'
  end
end

class Child1 < Parent
  attr_accessor :grade
  def initialize
    # superを指定しない
    @grade = 8
  end
end

class Child2 < Parent
  attr_accessor :grade
  def initialize
    super
    @grade = 8
  end
end

c1 = Child1.new #=> #<Child:0x00007fd583b2e6b0 @grade=8>
c1.name #=> nil (暗黙的に親クラスのinitializeが呼ばれるわけではない)

c2 = Child2.new #=> #<Child:0x00007fd583b2e6b0 @grade=8>
c2.name #=> Howord

参考

書籍:Effective Ruby

  • 項目7:superのふるまいがひと通りではないことに注意しよう
  • 項目8:サブクラスを初期化するときにはsuperを呼び出そう
Effective Ruby
Effective Ruby
posted with amazlet at 18.02.14
Peter J. Jones
翔泳社
売り上げランキング: 263,592

完全無欠コーヒーを1ヶ月続けて起きた体の変化

昨年末から完全無欠コーヒーを飲み始めて1ヶ月が経ちました。
自分の体に起こった変化を記録してみたいと思います。

始めた当時の以前の記事はこちら。
nesheep5.hatenablog.com

補足:飲み方アレンジ(プロテイン併用)

朝食を完全無欠コーヒーに置き換え、昼食まで他になにも摂らないのが正しい飲み方ですが、それだと胃のむかつきを感じてしまいました。
色々試してみて、プロテインを飲んでから完全無欠コーヒーを飲む方法で落ち着きました。
そうすることで胃を保護し、必要な栄養を補うことができます。
プロテインは糖質も少ないので、断食、糖質制限効果にも大きな影響はないのではと考えています。

ちなみに普段飲んでいるプロテインはこれです。

ホエイプロテイン 1kg 無添加 ナチュラル 
ボディウイング
売り上げランキング: 352

メリット

完全無欠コーヒーを1ヶ月続けてみて、良い変化がたくさんありました。

眠気がなくなる

以前は常に眠気を感じ、通勤電車や昼休みに寝ることが多かったのですが、全くなくなりました。
そのため、勉強やブログを書く時間を増やすことができました。(このブログも通勤電車で書いています)

疲れにくくなる

体が軽く感じ、頭もクリアになった感じです。
必要な栄養が体の隅々に行き渡っているような感覚です。
以前はなにをするにも、腰が重くやり始めるまでダラダラ時間がかかっていたのですが、今はスッと始められるようになりました。

目覚めが良くなる

以前は6時半ごろに眠い目をこすりながら起き、休み休み準備をしていましたが、
完全無欠コーヒーを飲み始めてから目覚めが良くなり、5時〜5時半には起きて出社の準備のほか、食器洗い、洗濯、ストレッチができるようになりました。

デトックス効果

完全無欠コーヒーを飲み始めて1週間後辺りから鼻水、たんが大量に出ました。
最初は風邪かと思ったんですが、体のだるさはなく、長く続くので調べてみたところ、断食効果によるデトックスのようです。
確かに、首や鎖骨のリンパがパンパンで触れると痛いくらいだったのですが、以前より和らいでいます。

体重、体脂肪が落ちる

あくまで生産性向上のために完全無欠コーヒーを飲んでいるのですが、体重にも良い効果が現れました。

体重 68.8kg → 67.6kg (1.2kgダウン)
体脂肪 20.3% → 18.3% (2.0%ダウン)

年末年始を挟んでこの結果なら上々かなと思います。
朝食を完全無欠コーヒーに置き換えることにより、プチ断食、糖質制限ダイエットのような効果があるとのことです。

デメリット

良いことだけではなく不調となった面もあったので、そちらも書いておきます。

胃のむかつきがある

冒頭にも書きましたが、慣れるまでの間、胃のむかつきがありました。
コーヒーと油だけなので、胃に刺激が強かったのかもしれません。
色々試し、プロテインを飲んでから完全無欠コーヒーを飲むことで解決しました。

便秘がちになる

完全無欠コーヒーを飲み始めてから、便秘がちになりました。
これは糖質制限ダイエットをしているとよくあるらしく、炭水化物を取らないことにより水分や食物繊維が不足することで起こるそうです。
完全無欠コーヒーを始めたら、水分・野菜をたくさん摂ることが大切なようです。

総評:生活の質が向上!完全無欠コーヒーオススメです

1ヶ月飲み続けてみましたが、日中の生活の質が高まっていることを感じました。
当初の目的だった、生産性向上に大きく貢献してくれています。
日々の生活の質を高めたい方、ダイエットしたい方にはとてもおすすめです!
興味があれば是非試してみてください!

2018年の目標

あけましておめでとうございます。
昨年は家を建てたり、子供が生まれたりと変化に溢れた年でした。
今年も充実して過ごせるよう、目標を掲げたいなと思います。

生活の目標

パフォーマンス向上

だるさや眠気、肩こり腰痛などを感じ、日中のパフォーマンスが悪いと常々感じていました。
今年は原因を一掃し、体力をつけ、パフォーマンスの向上に注力しようと思います。
また毎日のルーチンを見直し、ムダな時間を減らして時間を有意義に使おうと思います。

  • 肩こりを治す
  • 腰痛を治す
  • 睡眠の質を上げる
  • 運動する
  • 体脂肪15%以下
  • 筋肉をつける
  • 22時までに寝る
  • 5時半に起きて朝活
  • ムダな時間を削る

生活に必要な知識をつける

家庭を持ち、生活を送る上で必要な知識がたくさんあると感じました。
家庭の生活向上のため、少しずつ知識を貯めて家族と共有しようと思います。

  • 子育ての知識をつける
  • お金の知識をつける
  • 健康の知識をつける

家族を大切にする

前職では残業ばかりで家族との時間がとれませんでした。
転職して生活が安定してきたので、家族との時間を大切にしたいと思います。

  • 子供と目一杯遊ぶ
  • 妻とたくさん話す
  • イベントを大事にする
  • 両親、祖父母とまめに会う

家庭のカイゼン

家庭もひとつのプロジェクトとして捉え、日々カイゼンしていくべきと考えています。
今年はきちんと行動に移していこうと思います。

  • どんな家族になりたいか?(ミッション、ビジョン)を話し合う
  • 何歳で何をしたいか?(ロードマップ)を話し合う
  • 妻とお互いの目標を話し合う
  • どんな子どもになってほしいかを話し合う
  • やりたいことを話し合う
  • 普段困っていることを話し合う

仕事の目標

新しい技術を身につける

エンジニアとして成長するため、常にアンテナを高く張り情報収集します。 興味があったけど着手できていなかったことに挑戦したいと思います。

  • rubyをマスターする
  • railsをマスターする
  • AWSをマスターする
  • TDDを実践する
  • DDDを勉強する
  • チームビルディングについて勉強する

アウトプットする

アウトプットすることで自分の考えを整理し、また共感してくれる方との接点を増やしたいと考えています。
セルフブランディングの一環としても、積極的にアウトプットすることを意識します。

  • ブログを書く
  • OSSに貢献する
  • アプリを公開する

収入アップ

今までお金を欲しがることに恥ずかしさがあったのですが、会社への貢献度=年収として捉え、自分の成長度を測る指標である、と考えを改めることにしました。
評価面談時に目標を擦り合わせ、達成することで毎年少しでも年収アップするようチャレンジしたいと思います。
また会社の制度として正式に副業OKとなったので、何かできないか模索しようと思います。

  • 会社に期待されていること、自分のやりたいこと明確にする
  • 副収入について考える

目標を立てただけではダメ

いつも目標を立ててもすぐ忘れてしまうので、目につくところ(ブログ)に書き出してみました。
定期的に進捗を確認し、目標達成に向けて頑張りたいと思います。
皆さん本年もよろしくお願いします!