u16suzuの blog

日々学んだことのメモブログです。

Bundlerのエラー設計のメモ

  • Bundlerのエラー設計メモ
module Bundler
  class BundlerError < StandardError
    def self.status_code(code)
      define_method(:status_code) { code }

      if match = BundlerError.all_errors.find {|_k, v| v == code }
        error, _ = match
        raise ArgumentError,
          "Trying to register #{self} for status code #{code} but #{error} is already registered"
      end

      # 全てのエラーcodeリストを BundlerError に保持している. 上の部分で、同じ error code を登録しないためにそうしている。
      BundlerError.all_errors[self] = code
    end

    def self.all_errors
      @all_errors ||= {}
    end
  end

  class GemfileError < BundlerError; status_code(4); end
  class InstallError < BundlerError; status_code(5); end
  # message定義するケース
  class NoSpaceOnDeviceError < PermissionError
    def message
      "There was an error while trying to #{action} `#{@path}`. " \
      "There was insufficient space remaining on the device."
    end

    status_code(31)
  end
end
  • 例外をraiseするところ
raise BundlerError, "Unknown user path requested: #{dir}"
  • 例外ハンドリング周り
rescue GemfileNotFound
  bundle_dir = default_bundle_dir
  raise GemfileNotFound, "Could not locate Gemfile or .bundle/ directory" unless bundle_dir
  Pathname.new(File.expand_path("..", bundle_dir))
end

2018/1/8(mon) ホットサンドメーカーの使い方が上達した

ホットサンドメーカーで毎朝トーストを焼いているが、今日はとても上手く焼くことができた。 あんこを挟んでバターを乗せて小倉ホットサンドを作って見た。なかなかの味だった。

f:id:u16s:20180108150815j:plain:w300 f:id:u16s:20180108184041j:plain:w300

夜に妹から電話があり、姪に送ったモンテッソーリのおもちゃであるところのシリンダーというやつが届いたという連絡があった。 なかなか巨大なやつで、ブナの木でできており品質は良さそうで、大人からしてもスポット入り込んで行く感覚がとても気持ち良いそう。俺もやってみたい。

f:id:u16s:20180109002333p:plain:w600

明日からは久しぶりの仕事。今回は12/28~1/8までの12連休だった。かなりリフレッシュできたので明日から仕事頑張って行くぞという気持ち。

2017/12/31-2018/1/1,2,3,4,5 久々に名古屋に帰っていた

年末風邪気味だったのが徐々に落ち着いてきた頃に、名古屋に帰った。 RubyKaigiが開催された大須がとても近かったので、観光と初詣がてら行ってみたら、予想をはるかに超えた人の波でかなり混雑していた。 イメージ的には仙台の商店街をイメージしていたがそれよりもはるかに大須は巨大だった。大通りが複数あって、さらに脇道にも小さな商店や屋台がポツポツと軒を連ねており、近年ではグルメブームもあって食べ歩きの町として売り出しているらしい。

f:id:u16s:20180103130826j:plain:w300

写真はパオパオ亭の焼き包子(パオズ) 確かマツコの知らない世界で放送されていて、是非一度食べてみたかったやつ。噂通りの肉汁が出てきてとても美味しかった。ここは毎年のリピート決定。お土産で買って帰っても、フライパンで温め直してアツアツで食べることができて、みんなに美味しいととても喜ばれた。 1個160円なのでもっと多めに買って行ってもよかったかもしれない。

f:id:u16s:20180103132504j:plain:w300

からあげ彩音で食べた唐揚げもボリューミーで味が濃くて美味しかった。これでたったの500円。これをおかずにご飯を食べたかった。 真っ赤な唐辛子がかかっているけどそんなには辛くない。

f:id:u16s:20180103141952j:plain:w300

他には喫茶店やドックカフェに行ったり、コンパルのエビカツサンドを食べた。エビカツサンドは手羽先などに隠れてあまり目立たない名古屋飯かもしれないが、名古屋駅のすぐ近くのメイチカで買えてかつ、しっかり美味しいのでかなりおすすめ。 [コンパル メイチカ店](https://tabelog.com/en/aichi/A2301/A230101/23006112/

あとは、中古の宝石を扱うコメ兵というローカルチェーン店に行ってみた。興味本位で見ていると、宝石でも結構安いのが多くて、妻に後でそのことを話したら安いならば買ってきてくれればよかったのにと言われて、「余計なことを言ってしまった」という感じだった。

f:id:u16s:20180102110841j:plain:w300

2018/1/7 オブスキュラに久しぶりに行った

近くにある馴染みの神社である池尻稲荷に初詣に行ってきて、おみくじを引いたら大吉だった。おそらく人生初の大吉ではないかと思う。出産が安産だったのが何より。相場に山気を出すなと書いてあって、これは今年は仮想通貨には手を出さずにおとなしく投信でも買っておきなさいという神の啓示なのかもしれない。

学問に関心手は安心して励めという内容で、昨年からコツコツとよく使うツール周りの内部動作がどうなっているか知りたくて、時間のあるときにコードを追っている。普段何気なく使っているツール類でも内部挙動がどうなっているかを知っておくと安心感がある。こういう部分が、何か問題があった時の対応力につながってくると思う。

f:id:u16s:20180108162443j:plain:w300

その後、去年のお札を奉納した後に、あのフレッシュでとろけるようなレアチーズケーキが久しぶりに食べたくなって、三茶のカフェのマメヒコに行ったらあいにくの臨時休業だったので、久しぶりにオブスキュラまで足を伸ばした。酸味のあるあっさりしたコーヒーと、濃厚なチーズケーキをいただいた。

Reactのメモ

準備

sudo npm install -g react-tools
# jsファイルをwatch して自動ビルドをさせる
jsx --watch src/ build/

html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <script src="https://fb.me/react-15.1.0.js"></script>
    <script src="https://fb.me/react-dom-15.1.0.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  </head>
  <body>
    関数定義
    <div id="hello"></div>
    <br>
    クラスとして関数を定義
    <div id="hello2"></div>
    <br>
    component の中から別のコンポーネントを呼ぶ
    <div id="hello3"></div>
    <br>
    配列の内容を出力
    <div id="print_array"></div>
    <br>
    全部まとめて呼び出し
    <div id="all_sample"></div>
    <script src="build/hello.js"></script>
  </body>
</html>

javascript

  • ファイル名を hello.js として /src ディレクトリに保存すると、build されて /build/hello.js が生成される。
// 関数として定義
const Hello = (props) => {
  // props.name で引数取得
  return (
    <div className="Hello">
      Hello {props.name}
    </div>
  );
};
// 呼び出し
ReactDOM.render(
  <Hello name="Mr. Sato" />, // name で引数を指定
  document.getElementById('hello')
);


// クラスとして関数を定義
class Hello2 extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        Hello2
      </div>
    );
  }
}
// 呼び出し
ReactDOM.render(
  <Hello2 />,
  document.getElementById('hello2')
);


// component の中から別のコンポーネントを呼ぶ
const Foo = (props) => {
  return (
    <div>
      <Hello name="Mr. Suzuki"/>
      <Hello name="Mr. Kaede"/>
      <Hello name="Mr. Minato"/>
    </div>
  );
}
// 呼び出し
ReactDOM.render(
  <Foo />,
  document.getElementById('hello3')
);


// jsの配列の内容を出力
ar = [1,2,3,4]
/* comment */
const PrintArray = (props) => {
  // JSXの中で{}で変数展開できる
  return (
    <ul>
      {props.items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}
// 呼び出し
ReactDOM.render(
  <PrintArray items={ar}/>,
  document.getElementById('print_array')
);

// 全部まとめて呼び出し. renderは1つの要素のみ扱えるので <div> で全体を囲む必要がある
ReactDOM.render(
  <div>
    <Hello name="Mr. Sato" />
    <Hello2 />
    <Foo />
    <PrintArray items={ar} />
  </div>
  ,
  document.getElementById('all_sample')
);

トラブルシューティング

  • JSXについて何かしらの変換に失敗している場合、エラーログで教えてくれる便利
  • よくあるのは <Foo /><Foo \> と書いてしまうミス
built Module("hello")
["bar","foo","hello","style"]
hello.js changed; rebuilding...
Error while reading module hello:
Error: Parse Error: Line 21: Invalid regular expression: missing /
    at throwError (/usr/local/lib/node_modules/react-tools/node_modules/jstransform/node_modules/esprima-fb/esprima.js:2813:21)
    at scanRegExpBody (/usr/local/lib/node_modules/react-tools/node_modules/jstransform/node_modules/esprima-fb/esprima.js:1490:17)
    at scanRegExp (/usr/local/lib/node_modules/react-tools/node_modules/jstransform/node_modules/esprima-fb/esprima.js:1569:16)
    at parsePrimaryExpression (/usr/local/lib/node_modules/react-tools/node_modules/jstransform/node_modules/esprima-fb/esprima.js:3562:43)

実行結果

f:id:u16s:20171205013334p:plain

outer join を使ってみる

テストデータ

# towns table
id  name
1  アテネ
2  ヴェネチア
3  ローマ
5  ピサ

# users table
id  name    town_id
1  taro    1
2  jiro    2
3  saburo  3
4  shiro   4

inner join

  • town_id 4 のレコードは towns tableに存在しないので表示されない
select
  *
from
  users AS u
    join
  towns AS t
    on u.town_id = t.id
;

id  name    town_id id  name
1  taro    1  1  アテネ
2  jiro    2  2  ヴェネチア
3  saburo  3  3  ローマ

left outer join

  • こちらの outer join では town_id 4 のレコードは towns tableに存在しないので NULL になってる
select
  *
from
  users AS u
    left outer join
  towns AS t  
    on u.town_id = t.id
;

id  name    town_id id  name
1  taro    1  1  アテネ
2  jiro    2  2  ヴェネチア
3  saburo  3  3  ローマ
4  shiro   4  NULL    NULL

right outer join

select
  *
from
  users AS u
    right outer join
  towns AS t
    on u.town_id = t.id
;

id  name    town_id id  name
1  taro    1  1  アテネ
2  jiro    2  2  ヴェネチア
3  saburo  3  3  ローマ
NULL    NULL    NULL    5  ピサ

まとめ

  • inner join : 片方だけに存在するレコードは表示しない
  • outer join : 片方だけに存在するレコードはNULLで表示する. こちらはleft, rightの向きがある.