<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.2">Jekyll</generator><link href="https://til-hogucc.netlify.app//feed.xml" rel="self" type="application/atom+xml" /><link href="https://til-hogucc.netlify.app//" rel="alternate" type="text/html" /><updated>2025-02-01T13:54:40+00:00</updated><id>https://til-hogucc.netlify.app//feed.xml</id><title type="html">Hotil</title><subtitle>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</subtitle><author><name>hogucc</name></author><entry><title type="html">2025-02-01 Cache-Control</title><link href="https://til-hogucc.netlify.app//2025/02/01/til.html" rel="alternate" type="text/html" title="2025-02-01 Cache-Control" /><published>2025-02-01T00:00:00+00:00</published><updated>2025-02-01T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/02/01/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/02/01/til.html"><![CDATA[<h1 id="cache-control">Cache-Control</h1>

<blockquote>
  <p>Cache-Control は HTTP のヘッダーフィールドで、 キャッシュ をブラウザーや共有キャッシュ（プロキシーや CDN など）において制御するためのディレクティブ (指示) を、リクエストとレスポンスの両方で保持します。</p>
</blockquote>

<p>https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Cache-Control</p>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[Cache-Control]]></summary></entry><entry><title type="html">2025-01-31 When to use Devin ?</title><link href="https://til-hogucc.netlify.app//2025/01/31/til.html" rel="alternate" type="text/html" title="2025-01-31 When to use Devin ?" /><published>2025-01-31T00:00:00+00:00</published><updated>2025-01-31T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/31/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/31/til.html"><![CDATA[<h1 id="when-to-use-devin-">When to use Devin ?</h1>

<blockquote>
  <p>Start your day by putting multiple Devins to work in parallel:</p>
</blockquote>

<blockquote>
  <p>Think through your TODOs, and carve out small tasks that a team of interns (Devins) can help with.
Return to draft PRs waiting for review around lunch.
  Tag Devin on Slack threads for quick fixes:</p>
</blockquote>

<p>並行で走らせられるタスクならよさそう。</p>

<blockquote>
  <p>Devin is great for tasks that take &lt;30 minutes but often end up in large backlogs for weeks.
  Use the VSCode Extension for small refactors:</p>
</blockquote>

<p>すぐに解決するものはSlack使うといいのか。</p>

<blockquote>
  <p>The Devin VSCode Extension makes it easy to hand off work while you focus on your primary task.
Use Cmd+G to quickly share code snippets with Devin.
  Focus on easily verifiable tasks:</p>
</blockquote>

<p>自分の作業と統合したい場合はVSCode拡張を使うとよさそう。</p>

<blockquote>
  <p>Ideally, it’s as easy as checking that CI passes or testing an automatic deployment. Avoid ambiguous tasks where it can seem like the task was completed properly but something else is happening.
  Start small:</p>
</blockquote>

<p>抽象度の高いタスクを任せるのは厳しそう。</p>

<blockquote>
  <p>As you’re getting started, start many small runs to find the best use cases for Devin.
Try not to spend too many (&gt;10) ACUs on one run. Devin’s performance degrades in long sessions.</p>
</blockquote>

<p>まずは小さく始めて試行してみるのがよさそう。</p>

<p>https://docs.devin.ai/essential-guidelines/when-to-use-devin</p>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[When to use Devin ?]]></summary></entry><entry><title type="html">2025-01-29 [Active Record]count_all</title><link href="https://til-hogucc.netlify.app//2025/01/29/til.html" rel="alternate" type="text/html" title="2025-01-29 [Active Record]count_all" /><published>2025-01-29T00:00:00+00:00</published><updated>2025-01-29T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/29/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/29/til.html"><![CDATA[<h1 id="active-recordcount_all">[Active Record]count_all</h1>

<p>https://zenn.dev/igaiga/books/rails-practice-note/viewer/ar_usefuls#group%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8count%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89 から引用</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Book.group(:title).count
#=&gt; SELECT COUNT(*) AS "count_all", "books"."title" AS "books_title" FROM "books" GROUP BY "books"."title"
#=&gt; {"book0"=&gt;2, "book1"=&gt;2, "book2"=&gt;3, "book3"=&gt;1, "book4"=&gt;1}
</code></pre></div></div>

<p>countメソッドを使うとSQLにcount_allが指定される。
SQLにas xxxを書くと、ActiveRecordがattributesとしてxxxメソッドを作るため、以下のようにcount_allを使った書き方ができる</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Book.group(:title).order(count_all: :desc).count
#=&gt; SELECT COUNT(*) AS "count_all", "books"."title" AS "books_title" FROM "books" GROUP BY "books"."title" ORDER BY "count_all" DESC
</code></pre></div></div>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[[Active Record]count_all]]></summary></entry><entry><title type="html">2025-01-27 [Zod]or, union, discriminatedUnion</title><link href="https://til-hogucc.netlify.app//2025/01/27/til.html" rel="alternate" type="text/html" title="2025-01-27 [Zod]or, union, discriminatedUnion" /><published>2025-01-27T00:00:00+00:00</published><updated>2025-01-27T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/27/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/27/til.html"><![CDATA[<h1 id="zodor-union-discriminatedunion">[Zod]or, union, discriminatedUnion</h1>

<p>orやunionは、複数の型のどれか1つを許容するバリデーションを定義するときに使う。</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import { z } from "zod";

const stringOrNumber = z.string().or(z.number());
</code></pre></div></div>

<p>こんなかんじ。
orの代わりにunionを使うと3つ以上の型を許容できる。</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const stringOrNumber = z.union([z.string(), z.number()]);
</code></pre></div></div>

<p>discriminatedUnionは複数の型のうち、特定のキーを基にして型を区別できるユニオン型を作成できる。
z.unionとの違いは特定のキーを使うこと。オブジェクトがどの型なのかをキーで判別できる。
パフォーマンス的にもz.unionはすべての型を試行するが、discriminatedUnionはキーを使った型を一発で特定できるので処理速度が速い。</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import { z } from "zod";

const Dog = z.object({
  type: z.literal("dog"),
  breed: z.string(),
});

const Cat = z.object({
  type: z.literal("cat"),
  lives: z.number(),
});

const Animal = z.discriminatedUnion("type", [Dog, Cat]);

Animal.parse({ type: "dog", breed: "Labrador" }); // OK
Animal.parse({ type: "cat", lives: 9 });         // OK
Animal.parse({ type: "dog", lives: 9 });         // エラー
Animal.parse({ type: "fish", fins: 2 });         // エラー
</code></pre></div></div>

<p>例えばAPIのリクエストやレスポンスでオブジェクトの種類が異なるときに便利</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const CreditCardPayment = z.object({
  type: z.literal("credit_card"),
  cardNumber: z.string(),
  cvv: z.string(),
});

const PayPalPayment = z.object({
  type: z.literal("paypal"),
  email: z.string(),
});

const Payment = z.discriminatedUnion("type", [CreditCardPayment, PayPalPayment]);

Payment.parse({
  type: "credit_card",
  cardNumber: "1234-5678-9876-5432",
  cvv: "123",
}); // OK

Payment.parse({
  type: "paypal",
  email: "example@paypal.com",
}); // OK

Payment.parse({
  type: "credit_card",
  email: "example@paypal.com",
}); // エラー
</code></pre></div></div>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[[Zod]or, union, discriminatedUnion]]></summary></entry><entry><title type="html">2025-01-26 Heartbleed</title><link href="https://til-hogucc.netlify.app//2025/01/26/til.html" rel="alternate" type="text/html" title="2025-01-26 Heartbleed" /><published>2025-01-26T00:00:00+00:00</published><updated>2025-01-26T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/26/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/26/til.html"><![CDATA[<h1 id="heartbleed">Heartbleed</h1>

<blockquote>
  <p>ハートブリード（英語: Heartbleed）とは、2014年4月に発覚したオープンソース暗号ライブラリ「OpenSSL」のソフトウェア・バグのことである。</p>
</blockquote>

<p>https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%BC%E3%83%88%E3%83%96%E3%83%AA%E3%83%BC%E3%83%89</p>

<p>OpenSSLは暗号化通信に用いるライブラリだが、暗号化通信しても情報が漏洩することがわかった。</p>

<p>原因はOpenSSLのHeartbeatという拡張プログラムのバグで、悪意ある第三者が細工したリクエストが送信されるとメモリ上にある意図しないデータを返してしまっていた。
これによって個人情報やパスワードなどが盗まれる危険があった。</p>

<h3 id="参考">参考</h3>
<ul>
  <li>https://eset-info.canon-its.jp/malware_info/qa/detail/141204_1.html</li>
  <li>https://www.hitachi-solutions.co.jp/sbom/blog/2022021505/</li>
</ul>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[Heartbleed]]></summary></entry><entry><title type="html">2025-01-25 サブクエリを使ってクエリ発行回数を抑える（Active Record）</title><link href="https://til-hogucc.netlify.app//2025/01/25/til.html" rel="alternate" type="text/html" title="2025-01-25 サブクエリを使ってクエリ発行回数を抑える（Active Record）" /><published>2025-01-25T00:00:00+00:00</published><updated>2025-01-25T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/25/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/25/til.html"><![CDATA[<h1 id="サブクエリを使ってクエリ発行回数を抑えるactive-record">サブクエリを使ってクエリ発行回数を抑える（Active Record）</h1>

<p>https://tech.smarthr.jp/entry/2021/11/11/151444 を改めて読み返した</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Comment.where(post_id: Post.where(opened: true).pluck(:id))
</code></pre></div></div>
<p>これだとPostオブジェクトは作成作成されないけど、PostのpluckとCommentの取得で2回クエリが発行される。（SELECT id FROM posts WHERE opened = true　と　SELECT * FROM comments WHERE post_id IN (1個目のクエリで取得したid)の2回。1回目のクエリでidの配列が取れた配列を使って別のクエリを作っている。）</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Comment.where(post_id: Post.where(opened: true).select(:id))
#=&gt; SELECT "comments".* FROM "comments" WHERE "comments"."post_id" IN (SELECT "posts"."id" FROM "posts" WHERE "posts"."opened" = "true")
</code></pre></div></div>

<p>selectを使うとサブクエリ扱いになり、1回のクエリでCommentを取得できる。</p>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[サブクエリを使ってクエリ発行回数を抑える（Active Record）]]></summary></entry><entry><title type="html">2025-01-24 oklch</title><link href="https://til-hogucc.netlify.app//2025/01/24/til.html" rel="alternate" type="text/html" title="2025-01-24 oklch" /><published>2025-01-24T00:00:00+00:00</published><updated>2025-01-24T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/24/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/24/til.html"><![CDATA[<h1 id="oklch">oklch</h1>

<blockquote>
  <p>oklch() 関数記法は、指定された色を Oklch 色s空間で表現するものです。これは oklab() と同じ L 軸を持っていますが、極座標系の C （彩度）と H （色相）を使用します。</p>
</blockquote>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">oklch</span><span class="o">(</span><span class="err">40</span><span class="o">.</span><span class="err">1</span><span class="o">%</span> <span class="err">0</span><span class="o">.</span><span class="err">123</span> <span class="err">21</span><span class="o">.</span><span class="err">57</span><span class="o">)</span>
<span class="nt">oklch</span><span class="o">(</span><span class="err">59</span><span class="o">.</span><span class="err">69</span><span class="o">%</span> <span class="err">0</span><span class="o">.</span><span class="err">156</span> <span class="err">49</span><span class="o">.</span><span class="err">77</span><span class="o">)</span>
<span class="nt">oklch</span><span class="o">(</span><span class="err">59</span><span class="o">.</span><span class="err">69</span><span class="o">%</span> <span class="err">0</span><span class="o">.</span><span class="err">156</span> <span class="err">49</span><span class="o">.</span><span class="err">77</span> <span class="o">/</span> <span class="o">.</span><span class="err">5</span><span class="o">)</span>
</code></pre></div></div>

<p>https://developer.mozilla.org/ja/docs/Web/CSS/color_value/oklch</p>

<blockquote>
  <p>例えばデザインシステムのカラー設計で色相と明度（+彩度）を軸にしたカラーグリッドを作る場合でも、Oklchを使うことで視覚的に統一された色を簡単に作ることができます。</p>
</blockquote>

<p>https://blog.nasbi.jp/programming/frontend/css/good-looking-color-oklch/</p>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[oklch]]></summary></entry><entry><title type="html">2025-01-21 [UI]ドロワー</title><link href="https://til-hogucc.netlify.app//2025/01/21/til.html" rel="alternate" type="text/html" title="2025-01-21 [UI]ドロワー" /><published>2025-01-21T00:00:00+00:00</published><updated>2025-01-21T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/21/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/21/til.html"><![CDATA[<h1 id="uiドロワー">[UI]ドロワー</h1>

<p>ドロワーとは引き出しという意味で、ハンバーガーとセットで使われることが多い。
Notionの左のほうに配置されているメニューとかがドロワー。
あまり情報を入れ込みすぎると目的の情報が見つけづらくなるので要注意。</p>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[[UI]ドロワー]]></summary></entry><entry><title type="html">2025-01-20 PlaywrightのwaitForLoadState(‘networkidle’)は非推奨</title><link href="https://til-hogucc.netlify.app//2025/01/20/til.html" rel="alternate" type="text/html" title="2025-01-20 PlaywrightのwaitForLoadState(‘networkidle’)は非推奨" /><published>2025-01-20T00:00:00+00:00</published><updated>2025-01-20T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/20/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/20/til.html"><![CDATA[<h1 id="playwrightのwaitforloadstatenetworkidleは非推奨">PlaywrightのwaitForLoadState(‘networkidle’)は非推奨</h1>

<p>waitForLoadStateはページが必要なロード状態になるまで待ってくれる。
ロード状態は引数で指定できる（デフォルトは <code class="language-plaintext highlighter-rouge">load</code> ）
https://playwright.dev/docs/api/class-page#page-wait-for-load-state</p>

<p>渡せる引数は <code class="language-plaintext highlighter-rouge">domcontentloaded</code> <code class="language-plaintext highlighter-rouge">networkidle</code> <code class="language-plaintext highlighter-rouge">load</code> の3つ。
このうち <code class="language-plaintext highlighter-rouge">networkidle</code> は非推奨になっている。
<code class="language-plaintext highlighter-rouge">networkidle</code> は少なくとも500ミリ秒以上継続中のネットワークリクエストがない状態。
Playwrightの公式ではこの方法ではなくウェブアサーションに頼って準備完了を評価してください。としている</p>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[PlaywrightのwaitForLoadState(‘networkidle’)は非推奨]]></summary></entry><entry><title type="html">2025-01-19 Ghost</title><link href="https://til-hogucc.netlify.app//2025/01/19/til.html" rel="alternate" type="text/html" title="2025-01-19 Ghost" /><published>2025-01-19T00:00:00+00:00</published><updated>2025-01-19T00:00:00+00:00</updated><id>https://til-hogucc.netlify.app//2025/01/19/til</id><content type="html" xml:base="https://til-hogucc.netlify.app//2025/01/19/til.html"><![CDATA[<h1 id="ghost">Ghost</h1>

<p>GhostはNode.js製のオープンソースのブログエンジン。
フルマネージドで書くことに集中できる。
無料運用はできない（最安で月$9）。</p>

<h2 id="参考">参考</h2>
<p>https://ghost.org/pricing/
https://www.hanatane.net/why-ghost/</p>]]></content><author><name>hogucc</name></author><summary type="html"><![CDATA[Ghost]]></summary></entry></feed>