Effective Ruby: Struct便利だよ

項目10 構造化データの表現にはHashではなくStructを使おう

CSVファイルの取り込み時などに、それ用のクラスを作るの面倒だなという場合は、Structが良いというお話。 私もこの手のやつはHashだと扱いにくいので、自然とStructを使うようにしていました。
 
でも最近、Nestされた構造化データを扱うときにはHashが便利になるケースもあると最近学びました。
話がそれるので、この話はまたの機会に。
 
以下、本題。

Effective Ruby

Effective Ruby

Hashの問題点

CSVファイルの読み込み時などにHashを使ってしまうと以下のような問題が起きます。

1. keyを意識しないといけなくなる

要はインターフェースとして定義されていないので、利用する際に一々定義されている箇所を確認しないといけなくなります。
 

2. Hasnなのでゲッターメソッドでアクセスできない

そのままですが、他にもtypo時にNoMethodErrorが発生しない。
 

3. 各Hash間を操作するようなメソッドが作れない

例えば、各行に月間の気温統計のCSVがあるとして、そのデータの平均気温も知りたい場合、 各月の平均気温も知らないといけないが、それを定義する場所がない。

require('csv')
class AnualWeather
  def initialize(file_name)
    @readings = []

    # Hashのkeyを意識しないといけない
    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|
      # 各月の平均気温を求めるロジック
      # 本当はここだけ抽象化したい。
      # あとgetter method使えない。
      sum + (reading[:high] + reading[:low]) / 2.0
    end
    total / @readings.size.to_f
  end
end

Structを使うと

最初の2つの問題が解消されます。

class AnnualWeather
  # 項目定義が分離されて見やすい
  Reading = Struct.new(:date, :high, :low)

  def initialize
    @readings = []

    CSV.foreach(file_name, headers: true) do |row|
      @readings << Readings.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) do |sum, reading|
      # getter methodが使える
      sum + (reading.high + reading.low) / 2.0
    end
    total / @readings.size.to_f
  end
end

さらにblockを渡すことで

3つ目の問題が解消されます。

Reading = Struct.new(:date, :high, :low) do
  def initizlize
    super(date, high, low * 1.1)
  end

  # ここに定義できる。わかりやすい。
  def mean
    (high + low) / 2.0
  end
end

覚えておくべき事項

  • 新しいクラスを作るほどでもない構造化データを扱うときには、HashではなくStrutを使うようにしよう
  • Struct::newの戻り値を定数に代入し、その定数をクラスのように扱おう

 

余談

私はどっちかというと上記のblockを渡す方法より、以下のようにclassにしてしまって使うことの方が多かったです。
どっちでもいい気がしますが、以下の場合initializeを書くことができます。

  class Reading < Struct.new(:date, :high, :low)
    def initialize(date, high, low)
      # do something
      super(date, high, low * 1.1)
    end
  end

Effective Ruby: selfを書く場所

Effective Ruby

Effective Ruby

「項目8 サブクラスを初期化するときにはsuperを呼び出そう」は、そのまんまで 子クラスでinitializeメソッドを描く場合はoverrideされちゃうから、superを呼ぼうねという話でした(簡単なのでskip)。
以下本題。
 

項目9 Rubyの最悪に紛らわしい構文に注意しよう

これは、Ruby初心者なら誰しも引っ掛かる話ですね。

class Name
  attr_accessor(:first, :last)

  def initialize(first, last)
    # ここは必要
    self.first = first
    self.last = last
  end

  def full
    # ここは不要
    first + " " + last
  end
end

覚えておくべき事項

  • セッターメソッドは、明示的にレシーバを指定しなければ呼び出せない。レシーバがなければ、変数の代入と解釈されてしまう。
  • インスタンスメソッドからセッターメソッドを呼び出すときには、レシーバとしてselfを使う
  • セッター以外のメソッドを呼び出すときには、明示的にレシーバを指定する必要はない、selfでコードを汚さないようにしよう。

SLEEP 読了

こいつは、面白かった。  
内容的には、睡眠に良い・悪いとされる事柄についてホルモンとの関係性を示しながら、だからこうなんだよと書かれている。おすすめは前半。
章ごとにどうすれば良いのかというがまとめて書かれているのも良いです。

SLEEP 最高の脳と身体をつくる睡眠の技術

SLEEP 最高の脳と身体をつくる睡眠の技術

 
個人的にこういうの好きでノート取りまくった。
f:id:rochefort:20180205132643j:plain

知らなかった・良かったところをpick up

2章 睡眠ホルモンを自らつくりだす

セロトニン:快眠ホルモン。体内時計の調整をする。95%は目の光受容体で生成される。 皮膚が太陽から紫外線を吸収するときにも生成(ビタミンDセロトニン)。
(※必要な紫外線Bはガラスで遮断される)
 
メラトニン:寝る準備が整ったという信号を細胞に送る。外が暗くなるにつれて自然に分泌。睡眠の質を上げる。光を浴びた量に左右される。
 
コルチゾール:ストレスホルモン。朝増えて、夜に減る。眠りから覚ませ、機敏に動けるようにしてくれる。

3章 電子機器の使い方を見直す

ブルーライトコルチゾールの生成を促す。ドーパミンは覚醒させる。
 
ドーパミンは、実は快楽とは無関係。探求という行為に関係する
インターネット(ネットサーフィン)のようなものと相性が良い。注意力を高め、意識を覚醒させる。
 

4章 カフェインの門限は午後2時

起きている間、脳細胞は活発に動いてアデノシンという副産物が生まれ、これが増えると眠くなる。
カフェインは成分が似ておりアデノシンと結合できる。脳と体は活動を続け、本当は眠いのに気づかない。
 
カフェインの半減期は、5〜8時間と言われている。

5章 体深部の温度を下げる

体温が高いと眠れない。不眠症の人は体温が高い傾向がある。(冷やす帽子をかぶせると質・量共に改善するという結果あり)
ストレスが体温上昇をもたらす。(不眠症の人は先のことに対する不安を大きく抱えていたという調査結果あり)
 
室温は15〜20度にするのが良い。
 

6章 午後10時〜午前2時のあいだに眠る

ホルモンの分泌、疲労回復に良い時間。
午後10時ごろになるとメラトニンの分泌量が増える。代謝のエネルギー増加によって元気が回復したように感じる。

これ、ほんとそういう風に感じてた(特に会社で、、、)。  
深夜労働はガンを招く(他にも糖尿病も多い)、メラトニンは非常に強力なこうエストロゲン作業がある。
 

7章 腸内環境を整える

セロトニン粘膜にある超クロム親和性細胞によって生成される。
腸には脳内と同じ神経細胞が30種存在。メラトニンの95%はここで生成。
睡眠のリズムが不規則になると腸内毒素が生じ、代謝異常を招く。
人間の体内時計は最近のバランスに影響を受ける
睡眠不足は食べ物を選ぶときの判断力の低下、過食を招く。

8章 最良の寝室をつくる

ミエリン:脂質の一種。神経を覆って保護する。 同じ行動が繰り返されるたびに成長し、電気信号(情報)がスムーズに早く伝わるようになる。
 
寝室は寝るだけの部屋にすることで、寝室に入ったときに余計な電気信号を送らないようにする。

9章 夜の生活を充実させる

オキシトシンセロトニン、ノルエピネフリンノルアドレナリン)、バソプレシン、プロラクチン、テストステロンなどについて。要はセックスすると色々分泌されて睡眠に良いという話。

10章 あらゆる光を遮断する

皮膚にも光を感じる受容体がある。
人工光がメラトニンを現象させる。
LEDは特に睡眠の妨げになる。
 
子供の頃に寝るときに電気をつけると近視リスクに繋がるという調査結果も。

状況 近視になった確率
真っ暗 10%
豆球 34%
電気 50%

11章 熟睡したいなら運動するしかない

運動は睡眠の質を改善するが、夜に行うのはよくない。
朝行った方が、体の回復に見られる深いノンレム睡眠が多く見られた。
一度上がった体温は下がるのに4〜6時間かかる。
 
ちなみに染色体の末端にテロメアという配列があ理、染色体の破損やほつれを防いてでいる。
年齢を重ねるにつれて減り、最終的にはなくなる。縮める最大の要因は、睡眠不足
 
ウエイトトレーニングを週2回、2箇所の部位に対して行うのがおすすめ。
有酸素運動は、長時間行うと糖不足を補うために筋肉が分解され代謝が下がる。そのため走るのをやめると脂肪がつく。
 

14章 快眠をもたらす最高の飲酒法

アルコールは記憶の整理を行うレム睡眠を大きく阻害する。  
アルコールを摂取すると、アデノシン(起きていると増え、眠くなる)が増え、眠いと自覚する。
不自然にアデノシンの力が高まると身体は元に戻ろうとする。最初のレム睡眠は深くなるが、そのあとは浅くなる。
 

その他

90分サイクルを前提に書かれていたので、ここについては個人差があるし私は全く信頼していない。
以下のように、90分サイクルは都市伝説という認識。
あなたの朝が変わる! 「目覚め」解明SP - NHK ガッテン!