以前漆器を買ったときにすぐにダメになった経緯があり、より良い漆器を調達した経緯があるので、その損耗具合を追跡していく。
箸
この箸は大丸で2024年12月31日に購入した最も最初に買った漆器の生き残りだ。モノとしては箸蔵の品である。
箸なので使用頻度が非常に高く、菜箸を使うのが面倒な時に料理にまで使っているが、かなり酷使している割には意外と摩耗していない。この箸は非常に品質が良いと思う。
またプラ箸だと溶ける使い方をしても耐えてくれているし、百均の天然素材箸にありがちな塗装が剥離して口に入って不愉快な思いをするとかも起きていないため、大変満足している。
なお、隣にある汁椀は一ヶ月で漆が剥げまくり微妙になったので、香川漆器に買い替えた経緯がある。
汁椀
この汁椀は川口屋漆器店で2025年6月28日に購入したものだ。
比較すると摩耗はあるが、先代の汁椀と比べると全く問題がない。
この汁椀も扱いが荒く、最初のころはケトルの湯をそのまま注ぐことで摩耗が進んでいたが、直湯調理による漆器椀の摩耗を抑えるようにしたため、最近は比較的にマシになっているものと思われる。
この汁椀も前述の箸と同様に非常に品質が良いと思う。
お盆
このお盆も汁椀同様に川口屋漆器店で2025年6月28日に購入したものだ。
写真が上下逆になっていていてアレだが、こちらはほとんど変わっていない。
お盆としてはあまり使っておらず、もっぱらトーストを載せたり、餅を載せたりと、熱いものを乗せる皿として使っているが、食パンが二つちょうど乗るサイズなのもあり使い勝手はよい。
清掃についても、パンくずは払い落とせば終わるし、餅は水で洗えば落ちるので便利である。
実は角に打ち付けて破損したため、一度修理に出しているのだが、これについてはまた別に記事にしたい。
小スプーン
この小さいスプーンは大丸で2025年2月8日に購入したものだが、こちらも目立つ摩耗がない。これだけ工房がどこかわかっていない。大丸に聞いたら教えてくれるかもしれないで聞いてみようかな?
以前の損耗記事にも書いたが、大きいスプーンの方は損耗が目立ってきたので2025年7月26日に買い替えている。
大スプーン
先ほども書いた大きいスプーンは大丸で2025年7月26日に購入したものだが、こちらは摩耗がやや目立つ。モノとしては籐芸の品だ。
上の表では分かりづらいが、拡大してみると縁が削れている。これまで漆器を使ってきた中での傾向として、尖っている部分は摩耗しやすいことが分かっているので、長持ちする漆器を選ぶ場合は肉厚で丸みがあるものがよさそうだ。小スプーンは尖りがないので剥げてないし、汁椀も先代より縁が太めなので剥げが抑えられていると考えている。
黒文字
こちらも大丸で2025年7月26日に購入したもので、中田漆器の品だ。摩耗は目立たないが、角が若干剥げ気味だ。
上側の角をよく見ると薄っすら剥げてきている。気になるレベルではないものの、やはり宿命だろう。
わかりづらいが、菓子切りとして使う面は意外と剥げていない。
とはいえ、比較的剥げが少ないのは個人の工房のもので、値段もなかなかのものだからだろう。確か五本組で五千円ほどしたはずだ。つまり一本千円くらいする。
あとがき
漆器を一年少し使ってきてわかったこととしては、作りがちゃんとしており、値段がそこそこするものは耐久性がよいというのがまず一つ、次に漆器は熱湯にさえ気を付ければ割とガシガシ使っても大丈夫ということだ。
もう一つ、角のある漆器は漆が剥げやすいこと。特にスプーンはよく剥げるので、これはある種の宿命かもしれないと思った。
ここ最近諸事情でブログの更新全般が滞っていたので最近買ったものをいくつかまとめて書く。
貝印の爪ヤスリ
1月16日にアマゾンで購入。1000円程度。
どことなくオシャレな感じを醸し出している爪ヤスリ。
中身はこんな感じで裏表でヤスリの粗さが異なる。
ケースがあるため持ち運びに便利で、家の中でもカスが散らばりづらい。
爪切りに最初からついているヤスリより遥かに強力で、かなり強いので爪切りの代わりになるレベルの代物だ。あまりに優秀なため、家用と別に携帯用も買ったほど。
折り畳み爪切り
2月21日にロフトで購入。1,100円程度。
ビー・エヌというメーカーのMimits 3wayスリム爪切りという製品。ぶっちゃけ聞いたこともないメーカーだ。
開くとこんな感じ。畳むときは開いた背中を上にかぶせ、力押しすると閉じる。貧弱な作りを力任せに閉じるため、なんか壊れそうで心配だが、数回使った感じは特に大丈夫そうなので、しばらくは使えるだろう、多分。
収納用に柔らかいスリーブもあり、爪切りを入れておく小物入れを傷めないのもポイントだ。
出先で爪切りがなくて困ることが稀にあり、爪切りが欲しかったのだが、普通の爪切りだと邪魔なので折り畳み爪切りを探していたところ出会った品。
1,100円程度と手ごろな価格な割に、切れ味も悪くなく、実用性は十分だ。本当は貝印のが欲しかったのだが通販でしか見つけられず、それも八千円近くするため諦めた。
足の指を広げるやつ
2月21日にダイソーで購入。
さっきの爪切りを買うときに同じものをロフトで見つけたのだが500円もしたのでダイソーで買うことにした。
最近は高い店で物を買うことが増えたので、節約のために百均も少し見直していいかもしれないと思った。
指を広げられて気持ちいいので、たまに使っていきたい。
デスクチェア探しに一区切りがついたで、やや心残りな結果になったを何とかした話。
いい感じのオフィスチェアが欲しいでオフィスチェア(EX338 GTS129 BK)が座高が低いことと、後ろに倒れていることを問題にしていたが、もしかしたら座高が上がれば使えるのではないかということに気が付いた。
ということで、LIFELEX ゆったりレザー調チェア ニネヴェの座面をシリンダーから抜き取り、オフィスチェア(EX338 GTS129 BK)の座面と交換したところ、ぼちぼちハマった。
元々使っていたNシールドカルカと並べてみたところ。座高はばっちりだ。
比較すると、やはり背もたれがやや後ろに倒れているし、座面も前が盛り上がり、後ろに流れているが、深く腰掛けなければなくはない感じ。
どうしても元の椅子とは違うので百点満点とはいかないが、LIFELEX ゆったりレザー調チェア ニネヴェと比べると大分マシだし、最悪元の椅子が修理不能だった場合でも使っていける感じはするので満足だ。
最近二つほどツールを作り、Webツール置き場に配置したので、そこで得た学びや、作る時に意識したことについても書いてゆく。
ENV Checker
まずENV Checkerを作った話。
端的に言うとCyberSyndrome : ENV Checker - 環境変数チェッカーのパクリである。但しJSがないと動かない。
違いとしてはCyberSyndrome側で見れる情報のうち、ユーザー環境に起因しない情報を大幅に削り、ユーザー環境をメインに出せるようにしているほか、IPv4とIPv6の表示にも対応している。
作りとしては必要な情報を返すAPIを3つ用意し、ページを表示したときにJSがそれぞれを叩きに行き、その結果を表示している。
Get Enviroment APIはIPアドレス以外の環境変数を返却するもので、Get IPv4 APIはIPv4アドレスとホスト名、Get IPv6 APIはIPv6アドレスを返すように作ってある。
なぜこの様な分け方にしたかというと、Get Enviroment APIはIPのバージョンを問わない情報しか返さないが、IPアドレスまで返すようにするとIPv4に付随する情報やIPv6アドレスを返すことになるため処理が煩雑になる。
これは実装としてはCGIの環境変数をそのまま返しているのでREMOTE_ADDRに:が含まれているかどうかを見てIPv4か、IPv6かを振り分ける処理が必要になるからだ。
一方でGet Enviroment APIが環境変数だけを返すことに専念できるのならば、IPv4に付随する情報はGet IPv4 APIを叩けば取れるし、IPv6はGet IPv6 APIを叩けば取れるため、分岐処理が不要になる。
これによって各APIは単一の責務だけを持つことになり、コードの複雑化を回避できるといった寸法だ。この程度のシンプルな実装に求めることではないし、現状では無価値ではあるのだが、常日頃から意識することで、より複雑なものを作る時にも生かせるだろうし、将来何か改修するときにも作りが単純なほうが理解しやすいと思うので、こうしている。
IPv4とIPv6のAPIをどう分けているかというと、これはDNSレベルで解決している。Get IPv4 APIのエンドポイントにはAレコードのみを、Get IPv6 APIのエンドポイントにはAAAAレコードのみを設定することで、クライアントが接続する際に使用するIPバージョンを強制している。
こうすることで、各APIは単純にREMOTE_ADDRをそのまま返すだけでよくなり、IPバージョンの判定ロジックを一切持たなくて済むのが利点だ。欠点としてはAPIの数が一つ増えるため、管理コストは増えているといえるだろう。しかし分岐ロジックというのは往々にしてバグを生む存在であり、ないに越したことはないと思い、こういう設計にした。
また画面の描画をJavaScriptにさせているのも、こういったいわゆる関心の分離の思想によるところが大きい。やろうと思えばIPアドレス以外はCGIで表示して、IPアドレスのところだけをJSで書き換えることも、当然できる。出来るのだが、責務を分けるにはデータを返すだけのエンドポイントと、それを受けてJSで書き換える手法のほうが、より責務がはっきりしていて、わかりやすいのでこうしている。疎結合ということでもある。
項目値をダブルクリック・タップすることで値をコピーできるようにしているのも、地味だがこだわりポイントだ。
余談だが、先日Value-DomainでcertbotのDNS Challengeをやるスクリプトを書き直したのは、このドメインにTLS証明書を付与したり、DDNSできるようにする目的があったのが大きい。
というのも、このENV Checkerの開発にはipv4.lycolia.infoとipv6.lycolia.infoというドメインが関係しており、私の自宅サーバーの環境はIPv4がコロコロ変わるためDDNSが必須だった。
私が利用しているDNSレジストラであるValue-DomainはDDNS用のエンドポイントがあるのだが、1回1ドメインしか更新できず、60秒に1度しか叩けないという制約があり、これを回避するためには、Value-DomainのDNS APIに対して、一回で複数ドメインのAレコードを書き換える必要があった。
また同時に、以前使っていた、TLS証明書更新ツールである、value-domain-dns-cert-register (vddcr)はNode.jsのアップデートなどに伴う頻繁なメンテナンスが必要だったり、動作検証不足があったり、様々な面倒ごとがあり、これ以上触りたくなかった。
そんなこんなの流れがあり、ENV Checkerを作る中でOpenWrtからValue-Domainに複数サブドメインのDDNSを行うツールを作ったり、新たなTLS証明書更新ツールを作り、その検証をしたりしたのだ。
QRコードジェネレーター
もう一つはQRコードジェネレーターを作った話。
QRコードジェネレーターなどググれば無数に出てくるわけだが、意外と読み取り可能な最小サイズかつ、それをSVGで出力できるものを見つけることができなかった。そこで作ることにした。
とはいえ、作ったのはフロントエンドだけで、QRコードの生成自体はqrcode-svgを使わせてもらっている。これはこのライブラリのデモサイトで、理想の要件のものが作れることが分かったからだ。
なぜデモサイトで使えるのに、わざわざ作ったかだが、まずこのデモサイトでは最小サイズのQRコードを簡単に得ることが困難だったほか、256px以下のサイズにすることが想定されていないように見えたからだ。少なくともUIをクリックしてDIMENSIONを256px未満にしようとしても出来なかった。
また、デモサイトはいつか消える可能性もあるし、ブックマークするのも面倒なので、自分でホスティング出来るなら、それをするに越したことはなかったというのもある。
これを作っている中で得た学びとしては、カラーパレットの入力UIがWeb標準で可能になっていたことだ。そこら中で見かけるし標準であるんちゃうか?と調べたらあったので採用した。こういう複雑なものは昔であれば恐らく何かしらのライブラリを使うか、気合で作る必要があったと思うが、全く世の中は便利になったものだ。
また、こちらの実装方法については、HTMLの標準機能でカラーパレットを使ったカラーコード入力UIを作る方法の記事で紹介している。
他にもQRコードの周りには余白が必要ということも知れた。QRコードの開発元であるデンソーウェーブでは余白の求め方の計算式が解説されている。仕様上は適切な余白がない場合、読み込めない可能性があるようだ。これは恐らく周囲の図形とQRコード本体を光学的に分けて認識させるために必要なのだと思う。
なお、今回作成したQRコードジェネレーターには余白の自動調整機能は実装していない。理由は単純でサイズを自由に変えられる仕様上、帳尻をつけるのが面倒だからだ。要は手抜きである。
ついでにWebツール置き場の保守性や解りやすさを少し上げたりした
Webツール置き場のドメイン配下は元々全てペラのHTMLで実装していたのだが、ページが増えるごとに共通部分のhead要素の管理が煩雑になっていた。そこで、PHPに置き換えることにした。
結果として、以下のように、head要素の中身を共通化することができた。
まぁやっていることとしては高校時代にPHPで静的HTMLの内容を共通化していたのと何ら変わらないので、何故今更そんなことを…という感じだが、元々は静的HTMLで済むものは静的HTMLのほうが表示速度が速くシンプルでよいよなという意図で、静的HTMLにしていたのだが、数が増えてくるとそうも言ってられないということで対応した形だ。こういうのは事前に考慮しすぎると、早すぎる共通化やKISSの法則的なリスクを孕むと思っていて、定期的に振り返り、都度対応するほうが良いと感じている。いや、この程度の内容でそこまで考える必要はないと思うが…w
<!DOCTYPE html>
<html lang="ja">
<head>
- <meta charset='utf-8'>
- <meta http-equiv='X-UA-Compatible' content='IE=edge'>
- <title>Slackのリマインダーコマンドを作るやつ</title>
- <meta name="referrer" content="no-referrer-when-downgrade"/>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="author" content="Lycolia Rizzim">
- <meta property="og:image" content="https://tool.lycolia.info/slack-remider-creator/OGP.png">
- <meta property="og:site_name" content="Lycolia">
- <meta property="og:title" content="Slackのリマインダーコマンドを作るやつ">
- <meta property="og:description" content="必要事項を埋めることでSlackの/remindコマンドを生成するやつ">
- <meta property="og:type" content="website">
- <meta property="og:image" content="https://tool.lycolia.info/slack-remider-creator/OGP.png">
- <link rel="stylesheet" href="style.css">
- <script src="check.js"></script>
- <!-- Matomo -->
- <script>
- var _paq = window._paq = window._paq || [];
- /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
- _paq.push(['trackPageView']);
- _paq.push(['enableLinkTracking']);
- (function() {
- var u="https://analytics.lycolia.info/";
- _paq.push(['setTrackerUrl', u+'matomo.php']);
- _paq.push(['setSiteId', '3']);
- _paq.push(['enableHeartBeatTimer', 10]);
- var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
- g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
- })();
- </script>
- <!-- End Matomo Code -->
+<?php
+require_once('../template.php');
+
+renderCommonHead(
+ thumbnail: 'https://tool.lycolia.info/slack-remider-creator/OGP.png',
+ title: 'Slackのリマインダーコマンドを作るやつ',
+ description: '必要事項を埋めることでSlackの/remindコマンドを生成するやつ'
+);
+?>
</head>
template.phpの中身
関心ごとに関数を切り分け、呼び出される側は呼び出す側に依存するように設計することで、親が子の変更に引きずられないように保守性を意識した設計にしている。他にもほとんど固定値であるものについては運用を平易にする観点からOptional化して、初期値を設定している。
<?php
function buildMatomo() {
return <<<END
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.lycolia.info/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '3']);
_paq.push(['enableHeartBeatTimer', 10]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
END;
}
function buildCommonMeta(string $title, string $thumbnail) {
return <<<END
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>$title</title>
<meta name="referrer" content="no-referrer-when-downgrade"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="Lycolia Rizzim">
<meta name="thumbnail" content="$thumbnail">
<link rel="icon" href="https://lycolia.info/assets/brands/lycolia-32x32.png" sizes="32x32">
<link rel="icon" href="https://lycolia.info/assets/brands/lycolia-192x192.png" sizes="192x192">
<link rel="apple-touch-icon" href="https://lycolia.info/assets/brands/lycolia-180x180.png">
END;
}
function buildOG(
?string $thumbnail,
?string $site_name,
?string $title,
?string $description,
?string $type
) {
$tags = " <meta property=\"og:type\" content=\"$type\">\n";
$tags .= " <meta property=\"og:site_name\" content=\"$site_name\">\n";
if ($thumbnail !== null) {
$tags .= " <meta property=\"og:image\" content=\"$thumbnail\">\n";
}
if ($title !== null) {
$tags .= " <meta property=\"og:title\" content=\"$title\">\n";
}
if ($description !== null) {
$tags .= " <meta property=\"og:description\" content=\"$description\">\n";
}
return $tags;
}
function renderCommonHead(
?string $thumbnail = 'https://lycolia.info/assets/brands/lycolia-OGP.png',
?string $site_name = 'Lycolia.info',
?string $title = null,
?string $description = null,
?string $type = 'website'
) {
$head = buildCommonMeta($title, $thumbnail);
$head .= buildOG(
thumbnail: $thumbnail,
site_name: $site_name,
title: $title,
description: $description,
type: $type
);
$head .= buildMatomo();
echo $head;
}
また他にも、ドメイン直下にあるページの構造を見直した。
具体的にはulとliでリストにしていた部分をdl dt ddに直し、各ツールの内容を少し解りやすくした。ただ余りにも見た目が殺風景すぎるので、liに戻してカードUIをはめ込むようにするかもしれない。
投稿日:
いい感じのオフィスチェアが欲しいや、ゲーミングチェアなどの調査をしてきたまとめで椅子探しをしていたが、いったん区切りがついたのそのことについて書く。端的に言うと椅子を修理する当てを見つけたので、修理することに掛けてみることにした。
現状の椅子と修理について
まず座面の状態は急速に劣化しており、椅子のフレームから脱落しかかるほどになっていた。これは単にここ最近変な座り方をしているせいなのだが、なってしまったものはどうしようもない。
しかしニトリではもう売ってないし、修理依頼は断られるし、どうしようもなかった。
そこでどうにかならないかと調べていたら、革製品の修理を専門とする革研究所 神戸店というお店を発見した。
椅子の修理実績もあったため、早速声をかけてみたところ最大五万程度で修理できるだろうという見積もりが出たので依頼してみることにした。
しかし、現在は先客で埋まっているので、現物確認と作業可否判断は来月以降という話になった。何はともあれ、いったんこの椅子を使い続けられそうな光明が見えたのはありがたい。
とはいえ、この状態の椅子を使い続けるのは難しく、現物確認までの間や修理中に使える椅子は必要だったので、追加で椅子探しをすることにした。
新たに見てきた椅子
前回、ゲーミングチェアなどの調査をしてきたまとめでゲーミングチェアは不適当だろうということになったので、オフィスチェアを見ることにした。
家具屋を探しつくしている中、どこに行けば椅子があるだろう?と考えた時に思い付いたのがホームセンターだ。
LIFELEX ラウンドキャスターチェア パドリア
コーナン 灘大石川店にて確認。
| 項目 | 詳細 | 備考 |
|---|---|---|
| 座面高 | 43-55cm | かなり座面を高くできる |
| 素材 | PUレザー | |
| あぐら | × | 座面が狭すぎる |
| 価格 | 4,378円 | 非常に安価 |
- 座り心地は悪くない
LIFELEX ゆったりレザー調チェア ニネヴェ
コーナン 灘大石川店にて確認。
| 項目 | 詳細 | 備考 |
|---|---|---|
| 座面高 | 44-54cm | かなり座面を高くできる |
| 素材 | PUレザー+塩化ビニル | |
| あぐら | ◎ | |
| 価格 | 16,280円 | やや高め |
- 見た目に反してクッションが硬く、尻が痛くなる
- 肘当てを跳ねあげることができ、胡坐をかくことに支障がなく、座高を上げたまま机の下に入れるのも容易
- 手前より奥のほうが低く、ややふんぞり返る形になるため、作業向きではない
LIFELEX アンティークチェア クラロスII
コーナン 魚崎店にて確認。
| 項目 | 詳細 | 備考 |
|---|---|---|
| 座面高 | 45-53cm | |
| 素材 | PUレザー | |
| あぐら | × | 肘当てが邪魔 |
| 価格 | 10,780円 |
- 座り心地が良い
最終的に買った椅子
最終的にはLIFELEX ゆったりレザー調チェア ニネヴェを買うことにした。
座り心地だけを見ればLIFELEX アンティークチェア クラロスIIが一番よく、価格も安いからこれにしたかったが、肘置きの高さが机と衝突する高さだったため、値は張るが肘当てを跳ね上げることができるため、こちらを購入した。
この椅子は16,280円とやや高いが、それでもニトリのOC520と比べれば安価で、椅子の修理中にさえ使えるなら問題ないと判断した。
背中が群れるし、尻は痛いし、イマイチだが、価格からすれば及第点だ。せめてニトリのOC115 PVCの座高がもう少し高ければこちらにしたかったのだが、仕方ない。












































