プログラミングスクールのフィヨルドブートキャンプの提出物のレビューでよく指摘するシリーズ。

メソッド名に同じ名詞が頻出する場合、その名詞をクラス名として抜き出すとスッキリすることが多い。特にそれらのメソッドが同じインスタンス変数を使ってる場合は尚更。

Bad:

class File
  attr_accessor :permission

  def open
    # ...
  end

  def check_permission
    # ...
  end

  def fetch_permission
    # ...
  end

  def permission_characters
    # ...
  end
end

Good:

class File
  def open(path)
    # ...
    @permission = Permission.new(file)
  end
end

class Permission
  def initialize(file)
    @file = file
  end

  def check
    # ...
  end

  def fetch
    # ...
  end

  def characters
    # ...
  end
end

こんにちは、タイトルは昨今の流行を取り入れた自虐です😭

MacBook Pro 13inch 2020が来たので設定しつつ、いつもやっている設定を書きます。

キーボードや入力設定をする

まずはこれ。

  • CapsLockをControlにする。
  • キーリピートを最速に、リピート入力認識を最短にする。

App Storeからアプリをインストール

すでにインストールしてたやつをまた入れる。

  • CotEditor
  • Slack
    • みんな大好き。
  • Simplenote
    • 自分用のテキストはここに置いてます。
  • Kindle
    • PCで使うことは意外と多い。
  • TweetDeck by Twitter
    • こういうツールでホームのタイムラインは視界に入れないようにすると精神衛生上良い。
  • Xcode
    • 一応。

Homebrewをインストール

CLI系のアプリをインストール。

  • ghq
  • fzf
  • git
    • 新しい版を使いたい。
  • postgresql
    • 大好き。
  • mysql
    • 嫌いではない。
  • the_silver_searcher
    • 主にvimから全文検索するために使っています。もっといいものが最近はあるけど、vimgrepに比べたら超速いので満足してます。
  • tig
    • Unity+C#をやった時に大量のファイルをaddするのが辛くて使い始めました。
  • node
    • node-gypが憎い。
  • yarn
    • railsで必須だから以外に思い入れは無い。
  • pwgen
    • 手元でサッとランダムなパスワードを作りたい時のために。
  • screen
    • いい加減にtmuxに移りたいが同じ設定がtmuxでできず放置中。
  • go
    • あんまり書いてませんが、プログラムのディレクトリ構成はgoに合わせたままです。
  • rbenv
    • ~/.zshrcに設定を追記するのを忘れてスクールの生徒の方がいつもハマるやつ。
  • ruby-build
    • 最近色々オプションつけなくても良くなった気がする。
  • vim
  • hugo
  • imagemagick
    • 昔は荒ぶっていたが最近は大人しいヤツ。
  • ffmpeg
    • とっつき辛いが覚えれば一番ちゃんと動いてくれるやつ。
  • zsh
  • direnv
    • 特に無し。
  • hub
    • 特に無し。

Homebrew CaskでGUIアプリをインストール。

  • google-chrome
    • メインのブラウザです。
  • chromedriver
  • cyberduck
    • 滅多に出番はないけど慣れてるので使っちゃう。
  • fluid
  • messenger
  • sequel-pro
    • 最近不安定。
  • dbeaver-community
    • 使い辛いけど、Sequel Proが落ちる時に。
  • postico
    • 一番使うDBはPostgreSQLなのでお世話になってます。問題が起きたこと無し。
  • macdown
    • ブログなどの長文はこれで書いてます。
  • gyazo
    • いまだに神アプリ
  • discord
    • 自作キーボードのチャンネルに入る時に使ってます。
  • deepl
    • 翻訳すごいですね。
  • libreoffice
    • 主に他の会社の方のドキュメント編集用。Numbersは大抵崩れる。更に互換性が必要な場合はオンラインのOfficeを使う。
  • docker
    • メモリ喰い。
  • openemu
    • 最近中華ポータブルゲーム機にハマってるので。
  • steam
    • Windowsのゲーム用PCでは大活躍中だけど、macは仕事用なのでアンインストールした方がいいかもしれない。僕がやりたいゲームは大抵macでも動くのが困る。
  • sketch
    • 図を書く時に使う。以前Photoshopから移行してきた。
  • visual-studio-code
    • プログラミングスクールとしてはこれを前提としてるのでカリキュラムを作ったり、スクショを撮ったりする時に使います。
  • dropbox
    • 会社のドキュメントを共有してます。
  • 1password
    • 会社のパスワードを共有してます。

手動でアプリを入れる

App Storeにもhomebrewにも無いやつ。

  • zoom
    • 特に競合に対して優位性はないような気がする。

sshの鍵を入れる

USBメモリに入れてるsshの鍵をmacにコピー。

colinux上で作った鍵を使い回していて、セキュリティ的にまずいので作り直した方がよさそう。(今自分のブログを検索したところ2005年頃作った鍵のようだ)

dotfileをダウンロード

bitbucketで管理してたdotfileはgithubのprivateも無料になったのでgithubに移行しました。

シンボリックリンクを貼るsymlink.rbって昔書いたscriptをずっと使ってるけどずっと動いてる。

dotfilesを管理しよう - Qiita

仕事のプロジェクトを動かしてみる

いくつか動かしてみて動いたらOK。

ファイル共有

ドキュメントや画像なんかはicloud driveが安いのでほとんど入れてます。写真はGoogle Photos。

昔に比べるとクラウドで同期されるものが増えて、macを買った時の設定は楽になりました。

Mac設定の自動化

かっちりスクリプト or ツールで自動化しても、実行する機会が滅多に無いので、実行するたびに時代が変わっていてメンテナンスが必要になるのであまり楽にならないというあるある。(会社など複数人で使う自動化は意味がある)

最近のハードウェア・OSのアップデート戦略

以前は、

「毎年旧正月には禊として身を清めてから下ろしたての下着を履きクリーンインストールすべし。1年の垢と厄とキャッシュファイルをきれいにするのだ。」

などと言っていたのですが、

「OSアップデートもクリーンインストールもしない。2年に一度MacBookを買い換えれば良い」

という怠惰な戦略になっています。(最近はMacBookの進化が鈍化してるので買い替え頻度も落ちている)

ただ、上記に書いたように買い換えたときはTime Machineからリストアせず、まっさらから手動で設定しています。

フィヨルドブートキャンプでメンターとしてレビューしているときに、rubocopのカリキュラム以降は提出するコードをrubocopを通してから提出するようにお願いしています。

しかし、デフォルトのrubocopだと不便なところがあったのでfjordとしての設定を作りました。

方針は下記の2点です。

  • なるべくrubocopのデフォルトに従う。
  • rails newしたコードで指摘されまくるなど、流石にこれは厳しいという点のみ外す。

gistに置いたので下記のように書けば使えます。

.rubocop.yml:

inherit_from:
  - https://gist.github.com/komagata/9ad19373b9f9059ca52e727fbb7f2944/raw/e3a9bf5db5459a8172f634a677f7dccae66df060/ruby.yml
  - https://gist.github.com/komagata/9ad19373b9f9059ca52e727fbb7f2944/raw/e3a9bf5db5459a8172f634a677f7dccae66df060/rails.yml

require:
  - rubocop-minitest

Fjord rubocop configuration.

ruby用とrails用に分かれているのでrailsを使わない場合はそちらを読み込む必要は無いです。

それぞれgistのrevisionでURLが変わるので更新するには最新のURLを見に行って書き換える必要があります。

.vimrc:

let NERDTreeShowHidden = 1

なんで今までやってなかったんだろう?

ディスプレイの裏になんらかのフックを付ける。

Image from Gyazo

Image from Gyazo

Image from Gyazo

スッキリ!

フィヨルドブートキャンプでメンターとしてコードレビューをしています。自由な形式でプログラムを書く課題の場合、やはりオブジェクト指向プログラミングにみなさん苦戦しているようです。

特に、オブジェクト指向プログラミングのイメージが掴めないと、

「何をクラスメソッドにして何をインスタンスメソッドにすればいいのか」

がわかりません。(みんなここで詰まっている)

なので、これを説明するのはものすごく難しいんですが、挑戦してみます。

(クラスを定義する記法や使い方はRuby超入門などで読んだという方を前提とします。)

クラスとインスタンス

クラスインスタンス鋳型実体 だと考えてください。

鋳型とはこういうやつです。

Image from Gyazo

タイヤキの鋳型はタイヤキそのものとは別のものですが、その鋳型からできる全てのタイヤキの形を決めています。

Image from Gyazo

Person(人)クラスで考えてみます。

Person(人)というものは現実の世界にはいません。実際にいるのは駒形、町田といった人の実体です。哺乳類という動物がいないのと同じです。実際にいるのはポチやタマです。

Personにはname(名前)やage(年齢)といった属性がありますが、「そういう属性があるよ」ということは共通していますが、実際の名前はそれぞれ実体によって違います。

クラス変数とインスタンス変数

そうやって考えてみると、変数に関してはクラス変数(もしくは定数)とインスタンス変数のどちらにすべきか自然とわかると思います。

例えば「目の数」という属性はPersonに共通する内容なのでクラス変数(もしくは定数)がふさわしいです。「性別」という属性はインスタンスによって違うのでインスタンス変数がふさわしいです。

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

全てをクラス変数とクラスメソッドで処理するというのは手続き型プログラミングの世界です。

関数(メソッド)は極力引数の情報だけで処理が完結すべきというのは関数型プログラミングの世界です。

オブジェクト指向プログラミングでは、極力「インスタンス変数を使ってそのインスタンス自身に処理させる」というのが基本です。

例えばself_introduce(自己紹介する)というメソッドを作る場合、それぞれこうなります。

手続き型プログラミング:

class Person
  def self.name=(name)
    @@name = name
  end

  def self.self_introduce
    puts "I'm #{@@name}."
  end
end

Person.name = "komagata"
Person.self_introcude

関数型プログラミング:

def self_introduce(name)
  puts "I'm #{name}."
end

self_introduce("komagata")

オブジェクト指向プログラミング:

class Person
  def initialize(name)
    @name = name
  end

  def self_introcude
    puts "I'm #{name}."
  end
end

komagata = Person.new("komagata")
komagata.self_introduce

どれが良い悪いというのはないですが、オブジェクト指向プログラミングは最後のスタイルです。

極力、実体(インスタンス)が個別に持つ情報を利用してインスタンスメソッドを呼び出して処理する。そういう書き方が基本です。

例えば「人を探す」というメソッドがあった場合、(なんらかの人物が他の人物を探すとかでない限り)特定の実体には関係がないのでクラスメソッドが適しています。

class Person
  def self.find(name)
    # 探して新しいPersonインスタンスを返す
  end
end

実際は実装上の都合やテクニックが加わってくるのでこれに当てはまらない場合もありますがあくまで基本の考え方はこれです。

Image from Gyazo

フィヨルドブートキャンプでリアクションにGitHubにもあるアイコンに独自に少し追加したんですが、プログラミングスクールとしては💪がすごく使い勝手が良い。

すごく日本人的かもですが、頑張ります!とか頑張ろ!って意味ですごく使いやすい。

フィヨルドブートキャンプのカリキュラムでlsをrubyで実装するというのがあるんですが、パーミッションの八進表記を記号表記(symbolic notation)に変換する部分をどう実装するのがベターなのかなというのを悩んでおります。

rubyのFile::Statで取れるのは八進表記。

$ ruby -e 'printf "%o\n", open("./foo").stat.mode'
100644

これを記号表記 -rw-r--r--に変換したい。

このrとかwとかがどこで定義されているのかがわからなかった。

何か共通の定義があってrubyでも簡単に読み込めるならそれを使うべきだし、本物のlsでもプログラム中で個別に定義してるならruby内で自分も定義して使っちゃっていいのかなと考え、macのソースコードを調べてました。

twitterで@massoさんなどに助言をいただき調べたところ、Libcのstrmodeの中に書いてありました。(lsもstrmodeを使って表示している)

strmode.c

    /* usr */
    if (mode & S_IRUSR)
        *p++ = 'r';
    else
        *p++ = '-';
    if (mode & S_IWUSR)
        *p++ = 'w';
    else
        *p++ = '-';
    switch (mode & (S_IXUSR | S_ISUID)) {
    case 0:
        *p++ = '-';
        break;
    case S_IXUSR:
        *p++ = 'x';
        break;
    case S_ISUID:
        *p++ = 'S';
        break;
    case S_IXUSR | S_ISUID:
        *p++ = 's';
        break;
    }

chmodなどはこれを使ってなくて直接chmod.cに書いてあったりしました。

今のところrubyから簡単にstrmodeを使う方法もなさそうなのでrubyコードの中に自分で定義しちゃうのでいいのかなというのが現状です。

もし「こういう方法が一般的 or スマート」というのをご存知の方がいらっしゃったらtwitterの@komagataまで教えていただければありがたいです〜。

PC向けのスピーカーを探してたんですが、イマイチ可愛いのが見つかりません。自作すればスピーカーボックスが選び放題。カワイイやつも結構あったので初心者向けのセットを買いました。

ss

FOSTEX フォステクス かんすぴセット(6.5cm) KANSPI-6

Image from Gyazo

木ネジでスピーカーユニットを留めてケーブルをアンプに繋ぐだけ。スピーカーボックスもただの箱ですね。構造がシンプルなので壊れても修理が楽そうです。

Image from Gyazo

やった〜カワイイ!

音量の物理ツマミも欲しかったので嬉しい。

ゲーミングPCも同じのを共有してるのでヘッドホンしなくてもだらだらゲームができるようになりました。

プログラミングスクールのフィヨルドブートキャンプの提出物のレビューでよく指摘するシリーズ。

Bad:

# frozen_string_literal: true

class Foo
  require "optparse"

  attr_reader :xxxx

  def initialize
    # xxxx
  end
end

Good:

# frozen_string_literal: true

require "optparse"

class Foo
  attr_reader :xxxx

  def initialize
    # xxxx
  end
end

requireは主にライブラリを読み込むために使います。書いた場所のスコープに読み込むわけではないのでファイルの一番上(マジックコメントよりは下)に書くのが一般的です。

ついでにloadとの違いを押さえておくと良いかもです。