お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。

モダンからレガシーへ、ということで、これは前書いた記事の第二弾のようなものだ。モダンに逆らってレガシーへ変えてみる挑戦だ。

というわけで今回は調理器具を更新した。具体的には軽くて曲げやすい便利なプラスチック製のまな板とセラミック包丁から木製のまな板と金属製の包丁に変えたのだ。

樹脂製のまな板と、セラミック製の包丁
木製のまな板と金属製の包丁

実はセラミック包丁は前々からやめたいと思っていた。理由は単純で硬いものに使えないからだ。硬そうなものを切ろうとしようと怯えながら切らないといけない。そんな怯えながら料理をしたくなかったのだ。日々の料理は楽しいものでありたい。バリエーションもあった方がいい。そういう時に使途が限定されるものでは困ったのが一つだ。

もう一つは金属包丁の特性を調べていくと、セラミック包丁にはない特性があることが分かったのもある。何かといえばセラミック包丁は金属包丁と比べた時に切れ味が悪いということだ。例えば和平フレイズ公式ブログではセラミック包丁の特性として以下の説明がある。

次にセラミックですが、陶器である為もろいというお話をしたかと思いますが、刃を薄く仕上げてしまうと簡単に欠けてしまうので、セラミックの刃はかなり鈍角に仕上げられています。

こういった特徴があるので、例えば臭い移りを気にされる場合や、金属アレルギーをお持ちの方がお使いになる際はセラミックがお勧めです。

ただ、刃が鋭くないので切れ味を求められるのならば金属系のものをおすすめします。

個人的には切れ味の方が欲しいので金属の方がいいかなと思った。

また、まな板に関しても金属包丁を使う場合は木製の方がいいということが、これまた和平フレイズ公式ブログで紹介されていた。

これまではペラペラのプラスチックのまな板を使っていたのだが、心機一転、木のまな板にしてみようという思いもあり、木のまな板にすることに決めた。

買って使ってみた結果だが、まず買ったばかりなので包丁の切れ味はいいし、まな板もヒノキの香りがして非常に気持ちがよい。それとプラスチックのまな板は厚みが出ると非常に重いのだが、木のまな板は軽いので、これもよい。

今までのまな板と比べると鍋に切ったものを入れるのに少し苦労するが、風情があるので今のところは気にならない。何より国産のヒノキを使ったまな板で、製造も三重県で行っているらしいので親近感もある。やはり日本人であるからには日本製を使っていきたいものだ。このまな板は有限会社ウメザワさんの製品だ。

ついでに包丁立ても買った。まな板と包丁をしまう場所がなかったからだ。コンパクトに包丁とまな板を収納できる一品で一人暮らしにはうってつけのアイテムだ。

コンパクトに包丁とまな板を収納できる包丁立て

これは元々ニトリの商品だったと思うのだが取り扱いがなかったのでコーナンで買った。ニトリの製品はOEMが多いので終売になったらホムセンに流れることが多く、何なら販売中の商品がホムセンにあることもざらなので、ここは知っておくと便利なチップスだ。モノによってはドンキにあったりもする。

因みに今までのまな板は吊戸棚にぶら下げていたのだが、この吊り下げ方ができるまな板は限られるため丁度よかった。この時の包丁はシンク下の戸棚に備え付けの包丁差しに刺していたが、刺しづらいのと閉じ切った場所でイマイチだったので、今回の変更は悪くなかった。

吊戸棚からぶら下がるまな板

買って一週間ほど経ち、多少の不便は感じるものの、今のところ概ね満足している。これからも可能な範囲で古き良き日本文化というものを大切にしていきたいものだ。

WSLのUbuntuにRedmineを建ててnginxを通して適当なバーチャルホストでアクセスするまで

確認環境

Env Ver
Ubuntu 20.04.6
Ruby 2.7.0
Redmine 5.1.0
nginx 1.18.0

インストール方法

基本は公式の通り

DB作成

CREATE DATABASE redmine CHARACTER SET utf8mb4;
CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'my_password';
GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost';

インストールコマンド流す

wget https://www.redmine.org/releases/redmine-5.1.0.zip
unzip redmine-5.1.0.zip
cd redmine-5.1.0
cp config/database.yml.example config/database.yml

# DB接続は公式ドキュメントに沿って適当に設定する
# nano config/database.yml

sudo apt install -y ruby-full make gcc libmysqlclient-dev
sudo gem install bundler
bundle config set --local without 'development test'
sudo bundle install
bundle exec rake generate_secret_token
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production bundle exec rake redmine:load_default_data
bundle exec rails server -e production -p 9999 -d

nginxから繋ぐ

普通にリバプロするだけ

server {
  listen       80;
  client_max_body_size 100m;
  server_name  redmine.test;
  access_log   /var/log/nginx/redmine.access.log;
  error_log    /var/log/nginx/redmine.error.log;


  location / {
    proxy_set_header Host $http_host;
    proxy_pass  http://127.0.0.1:9999;
  }

}

トラブルシューティング

An error occurred while installing redcarpet (3.6.0), and Bundler cannot continue.

makeとgccがない

sudo apt install -y make gcc

An error occurred while installing mysql2 (0.5.5), and Bundler cannot continue.

MySQLの開発ライブラリがない

sudo apt install -y libmysqlclient-dev

"/usr/bin/ruby2.7: warning: shebang line ending with \r may cause problems" redmine

無視してよい

デフォルトポートを3000から変えたい

以下のように-pで指定

bundle exec rails server -e production -p 9999 -d

デーモンにしたい

以下のように-dで指定。殺すときはpkill rubyで行ける

bundle exec rails server -e production -p 9999 -d

Windows側のスタートアップで起動したい

不明。少なくとも以下の形式だと上手く動かない。

wsl -d Ubuntu -u root -- <command>

systemdを有効化すると色々不具合があるのでinit.dで起動できれば解決できる気はするのだが、上手くいかなかった。

投稿日:
ソフトウェア::GitOS::Linux::コマンド

特定ブランチ以外を全部消す

Git 2.25.1で確認

# マージされてないのは残す
git branch -d $(git branch | grep -vP <PCRE pattern>)
# 強制削除
git branch -D $(git branch | grep -vP <PCRE pattern>)

参考:git-branch - List, create, or delete branches (git-scm.com)

マージコミットをリバートする

Git 2.25.1で確認。基本-m 1で問題ないと思われる

git revert -m 1 <commit>

参考:git-revert - Revert some existing commits (git-scm.com)

コミット間のハッシュを見る

Git 2.25.1で確認

# 新しい順
git log --pretty=format:'%H' <commit>..<commit>
# 古い順
git log --pretty=format:'%H' <commit>..<commit> --reverse

参考:git-log - Show commit logs (git-scm.com)

投稿日:
言語::TypeScript開発::設計

TypeScriptで関数を書いているときに戻り値の型を書くケースがあるが、個人的にはあれは基本書かないほうがいいと思っているので、その理由を書いていく。

コード記述が冗長になる

まず型を書くと記述が冗長になる。以下のコードを見ると戻り値型が長く読みづらく、書くのも面倒だ。まずこんな長い命名をやめたほうが…というのはあれど、現実問題として長い命名は存在するので仕方ない。

export const getCampanyAndDepartmentAndEmployeeFromPrefectureCode = (
  param: VeryveryLoooongestParamTypeNaming,
): VeryveryLoooongestReturnTypeNaming => {
  return param.db.con.execQuery(
    "SELECT * FROM foo WHERE id = :?",
    param.dbParam.foo.id,
  );
};

しかし以下であれば戻り値型がない分すっきりしていて見やすいし、書く手間も掛からない。更に型推論によって正しい型が返るので理想的だ。

export const getCampanyAndDepartmentAndEmployeeFromPrefectureCode = (
  param: VeryveryLoooongestParamTypeNaming,
) => {
  return param.db.con.execQuery(
    "SELECT * FROM foo WHERE id = :?",
    param.dbParam.foo.id,
  );
};

実装と異なる戻り値型を暗黙的に記述できる

例えば以下のように書けば戻り値の型は'foo' | 'not foo'となり、常に正しい型が返る。

export const foo = (isFoo: boolean) => {
  return isFoo ? 'foo' : 'not foo';
};

しかし以下のように戻り値の型を定義すると実装上存在しない'bar'が返る。これは実装時に無用な混乱を生む。一般的にこのようなケースは仕様削除やリファクタなどで生まれることがあると思うが、そういうメンテ漏れにもなるので書かないほうが安全だといえる。

export const foo2 = (isFoo: boolean): 'foo' | 'not foo' | 'bar' => {
  return isFoo ? 'foo' : 'not foo';
};

他にも次のケースでは戻り値がstringとなり、何が返ってくるのかが実装を見ないと解らなくなる。特に理由がないなら書かないほうがよい。

// 'foo' | 'not foo'になるはずだがstring扱いになる
export const foo3 = (isFoo: boolean): string => {
  return isFoo ? 'foo' : 'not foo';
};

型記述が混乱する

ここは基本的に前項の内容と重複する内容となる。

例えば次の二つの実装は同じだが、戻り値の型だけが異なる。こういう実装が混在すると実装の一貫性が失われ無用な混乱を生むので、指定しないほうが望ましい。

const IndexPage = (): JSX.Element => {
  return (
    <Layout title={'Hello Next.js'}>
      <>
        <h1>Hello Next.js 👋</h1>
      </>
    </Layout>
  );
};

const IndexPage2 = (): ReactElement => {
  return (
    <Layout title={'Hello Next.js'}>
      <>
        <h1>Hello Next.js 👋</h1>
      </>
    </Layout>
  );
};

書いてもよいと思うケース

例えば依存関係を持たせたい時など、インターフェースとして型を共通化したい場合は書いてもよいと思う。これはどこでそれを使うのかが自明になるからだ。改修時にも型によって関連処理が見出しやすくなるので意識しやすくなる。

export const createPostMessage = (
  channel: string,
  username: string,
  message: string,
): PostMessage => {
  return {
    channel,
    username,
    message,
  };
};

export const postMessage = async (param: PostMessage) => {
  try {
    return await fetch('https://example.com/api/postMessage', param);
  } catch (err) {
    return err;
  }
};

但しこのようなケースではUnit Testを書いて、実装された戻り値型を満たす値が返ることを確認するのが望ましい。

戻り値型を書かないことによるデメリット

TypeScriptの公式リポジトリによると、型推論の速度に悪影響を及ぼすとあるので、型推論の速度が落ちるという点だ。

もし型推論の速度が非常に遅いと感じた場合は書いてみてもよいと思うが、公式でも以下のように案内があり、和訳すると「型推論は非常に便利なので、これを普遍的に行う必要はありませんが、コードの遅いセクションを特定した場合に試してみると便利です。」とあるので、余程複雑なことをしていない限り不要だとは思うし、そんな複雑な型を返すような処理は必要がなければ書かないほうがいいだろう。

Type inference is very convenient, so there's no need to do this universally - however, it can be a useful thing to try if you've identified a slow section of your code.

少なくとも私は実務上、型推論の速度に困ったことがないのと、tscでビルドすることも稀であるため、ビルドに影響することもない。よって基本書いていない。