OmniAICreator/Qiita-1.07M huggingface dataset:
初めてのChisel - コンパイル編


## プロジェクトのディレクトリ構造
Chiselを使用した開発にあたってScala制約の洗礼を受けます。代表的なものが**ディレクトリ構造の制約**です。

```
root--+--build.sbt
      |
      +--src--+--main--+--scala--"YOUR_SOURCE_CODES.scala"
              |
              +--test--+--scala--"YOUR_TEST_CODES.scala"

```

この構造にしないとHDL生成時にトップファイルを見つけることができず**ClassNotFound**エラーになります。


## コンパイル

コンパイルにあたって、SBTはプロジェクトディレクトリ構造に従ってそのディレクトリ内ををチェックします。SBTはトップモジュールを認識しそれに紐ずくファイル群をトレースしてクラス間依存を確認します。このため、トップモジュール（クラス）はどれかを指定してあげる必要があります。


### コンパイルの前に

コンパイルにあたって次の事項を定義しておく必要があります。

1. [オプション] **プロジェクト名**:
プロジェクト名は開発するプロジェクトのアイデンティティです。固有の名前を定義することをお勧めします。この名前は``build.sbt``ファイルに定義することで、実行中のスクリプトが何かを認識できるようになります。従って複数管理する場合ヒントになります。

2. **トップクラス**
HDLと同じくトップモジュール（クラス）はどれかを指定します。どのクラスがトップかを指定するにあたり、適宜固有な名前をクラスに付与してください。

3. "YOUR_TEST_CODES.scala"
**iotesters**で使用します。

## トップクラス
トップクラスの記述はトップクラスのファイルに次の構文を付与すれば問題なくChiselはチェックできコンパイルに移行することができます。"ProjectName"を自分のプロジェクトの名前に置き換えてください。

```object ProjectNameMain extends App {
  chisel3.Driver.execute(args,()=>new ProjectName("_args_"))
}```

```_args_``` はそのトップモジュール（クラス）が継承している引数を表現していますので、クラスで引数を使用していなければ不要ですが使用している場合間接的でも良いので引数を指定しておく必要があります。

## コンパイル方法
ターミナルでコンパイルすることになると思いますが次のコマンドでコンパイルできます。

```
sbt 'run'
```

SBTはコンパイルにあたってどうしたいかを質問してきます。可能なオプションから番号を指定してコンパイルを行います。
あるいは、直接的に先に定義した```ProjectNameMain```を指定してコンパイルをすることもできます。

```
sbt 'runMain ProjectNameMain'
```

パッケージ名``package_name``を予め指定している場合（複数の同じクラスが存在していてそれを区別するためにパッケージ名を使用している）、パッケージ名も指定してコンパイルすることをお勧めします。

```
sbt 'runMain package_name.ProjectNameMain'
```



``runMain``は``ProjectNameMain``を呼び出しコンパイルを行い、HDLを生成します。
Tailwind CSSの導入

#Tailwind CSSとは
CSSプロパティを予めラップしたクラスのユーティリティ集です。
これらをHTMLタグのclassnameに直接指定するので、cssファイルを使用する必要がなく、可読性が上がります。
また、BEMやOOCSS等の命名規則に縛られる必要もありません。
メリットは記述量の削減や可読性向上、ファイルサイズの縮小等があり、デメリットはクラスの記述が増加することと、それらのユーティリティクラスを使いこなすのが面倒である事です。

```css:.css
div {
  display: flex;
  justify-content: center;
  font-size: 0.875rem;
  line-height: 1.25rem;
}
```
```tailwind:tailwindcss
<div className="flex justify-center text-sm">
  <p>Hello World</p>
</div>
```

####チートシート
https://nerdcave.com/tailwind-cheat-sheet

##導入方法
以下の公式サイトからインストールを行います。

https://tailwindcss.com/

installationから使用しているフレームワークを選択すれば、各フレームワークのインストールから手順を確認できます。
ここではNext.js環境にてインストールを行います。

####インストール

```
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npx tailwindcss init -p
```

####Tailwindの設定
インストールが完了すると、プロジェクトフォルダ直下にtailwind.config.jsが作成されます。
今回は以下のように、purgeの設定のみ変更します。

```
module.exports = {
  purge: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
};
```
purgeはデプロイ時にクラスユーティリティを生成するファイルを決定します。
デフォルトでは全てが対象で膨大な量となるので、pagesとcomponents配下を指定します。

####インポート
プロジェクトファイル内でTailwind CSSをインポートします。

```app:_app.js
import "tailwindcss/tailwind.css";
```
続いて、プロジェクトのcssファイル内でtailwindをインクルードします。
cssファイルの名称はフレームワーク毎に異なります。
ここではNext.js環境なので、globals.cssに以下を記載します。

```css:globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
これで基本的な環境設定は完了です。

##VSCodeで入力補完
Tailwind CSSのユーティリティクラスを入力補完してくれる拡張機能をインストールします。
Marketplaceで「__Tailwind CSS IntelliSense__」をインストールします。
settings.jsonに以下の変更を加えます。

```set:settings.json
{
  "editor.tabSize": 2,
  "workbench.tree.indent": 2,
  "editor.suggestSelection": "first",
  "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
  "tailwindCSS.experimental.classRegex": [
  ],
  "editor.quickSuggestions": {
    "strings": true
  }
}
```

問題なく入力補完が効いていれば完了です。
![スクリーンショット 2021-12-01 13.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286658/5b20579c-c7d8-3eb8-e6bc-de7419f1892f.png)
2021年のAtom Editor


## GitHub社はMicrosoft社に買収された

元々VSCode（Microsoft社製）とAtom（GitHub社製）は競合関係にあるエディタでした。しかし、2018年にGitHub社がMicrosoft社に買収されたことで、両者ともにMicrosoft社が維持管理を行うことになりました。

当時は「AtomはVSCodeに吸収されて消滅するのではないか」との憶測も出回りましたが、次期CEO（当時）が否定しています。

https://www.reddit.com/r/AMA/comments/8pc8mf/comment/e0a2b2e/?utm_source=share&utm_medium=web2x&context=3

しかし、VSCodeとAtomの間には差がついてしまっているのも事実です。

### VSCodeに比べて開発速度が遅い問題

2021年1月1日から12月1日までに公式リポジトリ上で開かれ、マージされたプルリクエストの数を、VSCodeとAtomの間で比較してみます。

https://github.com/atom/atom/pulls?q=updated%3A%3E%3D2021-01-01+-author%3Aapp%2Fdependabot+is%3Amerged
https://github.com/microsoft/vscode/pulls?q=updated%3A%3E%3D2021-01-01+-author%3Aapp%2Fdependabot+is%3Amerged

記事執筆時点では、Atomが238件、VSCodeが1889件と、VSCodeに大差を付けられてしまっています。
また、これは筆者の体感ですが、GitHubにissueを上げた時の対応速度も遅い気がします。

### GitHub Copilotが来ない問題

GitHub CopilotはVSCode、Neovim、JetBrainsIDEでサポートされているものの、Atomのサポートはありません。
そもそもAtomはGitHub社のものだったので、GitHubのサービスが真っ先に導入されてしかるべきだと思うのですが…

### パッケージのメンテナンスが終了している問題

例えば、私が愛用している[atom-runner](https://github.com/lsegal/atom-runner)パッケージ（8万DL）は5年前に更新が止まっています。Go言語向けのコード補完などを実装したIDEパッケージである[ide-go](https://github.com/ckaznocha/ide-go)パッケージ（7万DL）は2年前に更新が止まっています。他にも、更新が止まっているパッケージはそこそこの頻度で見かけます。
上で紹介した2つはそれぞれ代替パッケージは出ているのですが、ユーザーが十分移行しているかというと不完全だと思います。
Atom自体の更新が緩やかなので、パッケージが今すぐ使えなくなるといった事態には陥っていませんが、コミュニティの規模が縮小しているのを感じます。

### まだCoffee Script使ってる問題

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/f80a212c-9d53-06ca-f46d-465dbb173b42.png)

▲Atomのコードに含まれている言語の割合（githubより）

Atomの内部コードにはまだCoffee Scriptを使っている箇所があります。
TypeScriptで開発されているVSCodeとは対照的です。

このように、Atomを取り巻く状況はあまり良いとは言えない状況です。しかし、AtomはOSSなので、有志によって継続的な更新を行おうという取り組みがあります。それが、次に紹介するAtom Communityです。

## Atom Communityの誕生

https://atom-community.io/

Atom公式チームとは別に、Atom周りの開発を行うコミュニティが誕生しています。その名もAtom Communityです。

Atom Communityでは、

- Facebookが放棄したatom-ide-uiパッケージの更新の引き継ぎ
- リポジトリを更新が終了しそうなパッケージの管理をAtom Communityで引き受けることで、主要パッケージの更新停止を防ぐ
- Atom本体のForkを作成し、Community版として維持

といった活動が行われています。

Atom Communityからリリースされているパッケージは、TypeScriptでの開発やCIによるテスト、リリースなどが行われており、これからAtomパッケージを開発しようとしている方にとっては参考になると思います。

## まとめ

- AtomはVSCodeに押され気味
- 開発は続いている
- コミュニティ主導でAtom周りのエコシステムを維持管理していこうというプロジェクトもある

Vim対Emacsの話題はTwitterでよく見かけますが、Atom対VSCodeの話はめったに聞かなくなりました。みんなもっとAtomで盛り上がりましょう。
Swiftで複数ファイルを纏めて圧縮..圧縮ぅ！！

## 事のきっかけ
GUI的には直ぐにできる操作だけども、Swift的にどうすれば良いのか気になった次第。

## 使用技術
- [Zip Foundation](https://github.com/weichsel/ZIPFoundation): Swiftネイティブで圧縮するライブラリ。
- [Swift](https://www.swift.org/documentation/): プログラミング言語

## 開発環境
- macOS Big Sur Intel Mac
- Xcode 13.1

## 内容

### フォルダ構成

Documentフォルダにworkフォルダを作成して保存

```text
[Document]
|-[work]
    |- test.png
    |- test.txt
    |- test.yaml
  
```

### 手順(上から順に)
- [参考サイト](https://iiroalhonen.medium.com/adding-a-swift-package-dependency-in-xcode-13-937b2caaf218)を参考にZipFoundationのパッケージをインポート

- main.swiftに下記を記載して実行。

```swift:main.swift
import Foundation
import ZIPFoundation

func archiveFile() throws -> Void {
  // fileManager
  let fileManager = FileManager()
  
  // User Document Folder
  let path: URL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
  let workingPath: URL = path.appendingPathComponent("work", isDirectory: true)
  print("====WORKING-PATH=====")
  print(workingPath)
  print("=====================")
  
  // get Working Contents
  guard let workingContents: [String] = try? fileManager.contentsOfDirectory(atPath: workingPath.path) else {return}
  
  // filter .DS_Store
  let filteredworkingContents: [String] = workingContents.filter{$0 != ".DS_Store"}
  let sourceURLs: [URL] = filteredworkingContents.map{workingPath.appendingPathComponent($0, isDirectory: false)}
  print("====SOURCE-URLS======")
  print(sourceURLs)
  print("=====================")

  // create tmp folder
  do {
    try fileManager.createDirectory(at: workingPath.appendingPathComponent("tmp", isDirectory: true), withIntermediateDirectories: false, attributes: nil)
  } catch {
    print("ERROR")
  }
  
  let archiveURL = workingPath.appendingPathComponent("tmp/test.zip", isDirectory: false)
  print("=====ARCHIVE-URL=====")
  print(archiveURL)
  print("=====================")
  guard let archive = Archive(url: archiveURL, accessMode: .create) else {
    throw Archive.ArchiveError.unwritableArchive
  }
  do {
    try sourceURLs.forEach{
      try archive.addEntry(with: $0.lastPathComponent, relativeTo: $0.deletingLastPathComponent())
    }
  } catch {
    print("Error")
  }

}

try archiveFile()
```
## ここに至るまで。

特定のファイルをZip化したいと思い、やり方を調べていたが、ZipFoundationの公式サイトを見ても書いておらず、日本語のサイトや英語のサイトを探索したが全くと言っていいほど情報がなかった。
しかし、公式サイトにはディレクトリを指定する事で纏めてZip化しているサンプルコードがあったため、このサンプルコードをよすがにコードをたどる事で見つけることができた。

## まとめ
ドキュメントだけでなく、利用するライブラリのコードを直接見ることで、事細かにカスタマイズできることを改めて認知した。
【Unity】PostProcess トラブルシューティング

# 通常のカメラにはPostProcessが反映されるが、RenderTextureには反映されない。
RenderTextureのColorFormatが16bit未満の場合、PostProcessが反映されない。
R16G16B16A16_SFLOAT等に設定すること。

https://forum.unity.com/threads/camera-render-texture-with-post-processing.817674/
React.memoを使いつつ型引数を利用する

## はじめに
型引数を受け取るコンポーネントに`React.memo`を利用するとそのままでは型を渡すことができません。
そのような際の簡単なハックを記載します。

## 例

以下のコンポーネントがあったとします。

```tsx
type Props<T> = {
  value: T;
}

const SomeComponent = <T>({ value }: Propd<T>) => {
  return ...
};
```

`React.memo`の返り値は型引数に対応していないのでそのまま`React.memo`を利用すると以下のような定義になりコンポーネントに対して型を渡すことができなくなります。

```tsx
const Memoized = React.memo(SomeComponent);
// const Memoized: React.MemoExoticComponent<(<T>({}: SomeProps<T>) => JSX.Element)>

<Memoized<number> value={1} />;
// -> TS2558: Expected 0 type arguments, but got 1.
```
※ この用途であれば`<number>`を渡さなくても問題ないのですがシンプルな例として記載しています

## 解決方法

以下のようにすることで対応可能です。

```tsx
const Memoized = React.memo(SomeComponent) as typeof SomeComponent;

// そのままexportも出来ます
export default React.memo(SomeComponent) as typeof SomeComponent;
```

シンプルですが利用する頻度も多いと思うので誰かの役に立てるよう残しておきます
初めてのChisel - インストール編

Chisel使用にあたっての事前準備紹介です。内容は以前英語で書いたものを加筆修正し、日本語訳にしたものです。

## この記事の対象者
Chiselに興味があるけど使ったことがなく、とりあえず触ってみたい方。Scalaスクリプト言語で高位記述でハードウェア記述を体験してみたい方。

## Chiselって何?
ChiselはHDL(Hardware Description Language;　ハードウェア記述言語)を生成するスクリプト言語です。Java系のScalaスクリプト言語を基にしていて、文法規則も基本それに従いますが、Chiselではハードウェア記述のためのプリミティブなクラスや文法が追加されています。Scalaコーディングライクにハードウェア設計ができる特徴を持ちます。現在のChiselのバージョンはChisel3で、リリースバージョンは3.5が最新です。Scalaはオブジェクト指向プログラミング言語ですので、それに従ってChiselではハードウェアを**クラス**として定義してそれを基にHDLを生成します。

## 事前準備

予め必要なものは以下のとおりです；
- Java Runtime Environment (or JDK, Scala実行のための大元の言語)
- SBT (Simple Built Tool, Chisel(Scala)実行のための環境)
- インターネットワーク環境

### 一般的なインストール手順

初めに事前準備のソフトについて説明します。
- Java Runtime Environment (JRE)
  
おそらくJREはPCにデフォルトでインストールされていると思いますが、念のために次のコマンドをターミナルで試してみてください。

```java -version```

バージョン情報とともに実行されない場合、インストールされていません。Macであれば***homebrew*を使用してインストールできます。Ubuntuの場合、**apt**を使用してインストールできます。次にインストールするSBTはオープンソースJavaなのでOracle社のものではなくOpenJDKの方が必要です。
https://openjdk.java.net/  

- SBT

    インストール方法は次のWebサイトに記載されています。
    https://github.com/freechipsproject/chisel3/wiki/Installation-Preparation
    SBTはインストールの際にOpenJDKを呼ぶのでデフォルトでOracle社のものがインストールされている場合、別途先に説明したJREをインストールしてください。

## インストール

**注意**: インストール前にChisel利用にあたり自分がどちらの利用者か確認してください。どちらの利用者かで適切なインストール方法が異なります。
    - **一般**利用者：chisel記述したプログラムからHDLを生成する目的で使用したい。Chiselは一般的なもので良いので**リリース**されているchiselを使用すれば十分です。ローカルにインストールしなくても利用できます。その代わりネットワーク環境が必要です。
    - **開発**利用者：最新のChiselバージョンが必要（例えば**rc**バージョンを使いたいなど）だったり、ローカル環境で開発環境を帰結したい方、Chiselソース高度に触れてカスタマイズしたい方。おそらく**プリリリース**されているchiselを使用したいのではないでしょうか。

### 一般利用者向けのインストール方法

ChiselはSBTで実行する際に**build.sbt**という実行するバージョン指定などが記述された環境ファイルであり、これを参照します。このファイルには**リリース**バージョンの一般的な定義が記載されており、SBT実行時にMavenサーバにアクセスしますのでネットワーク環境は必須です。build.sbtファイルを更新すれば常に最新の環境でChiselを使用できます。予めテンプレートのbuild.sbtが用意されていますので定期的にこのテンプレートを更新すれば良いだけです。
テンプレートはここにあります：

https://github.com/freechipsproject/chisel-template

**コピー＆ペースト**をプロジェクトディレクトリで行えば良いだけです。これでChiselの環境は整いました。コーディングしてコンパイルしてみてください！


### 開発利用者向けのインストール方法

ローカルコンピュータにインストールしたい場合、Chiselなどのツールをコンパイルしてインストールする必要があります。インストールまでの手順は次のとおりです。

```sbt compile```

コンパイル後に実行可能なファイルにします。

```sbt assembly```

そしてローカル環境で使用できるようにします。

```sbt publishLocal```


- Coursier  
  
Coursierを使ってインストールすることもできます。FIRRTLを例に説明します。次のコマンドでcurlを使用してCoursierをローカル環境にインストールします。

```curl -fLo cs https://git.io/coursier-cli-linux && chmod +x cs && ./cs```

このコマンドで実行可能なCoursierがファイル名"cs"として生成されます（もちろんCourssierが事前にインストールされていればこのステップをスキップできます）。この後にFIRRTLをインストールします。

```./cs bootstrap edu.berkeley.cs::firrtl:1.3.2 --main-class firrtl.stage.FirrtlMain -o firrtl-1.3.2```

Coursierに登録されているバージョンに限定されることに留意してください。上記コマンドでは```firrtl:1.3.2```でバージョンを指定して、```-o```オプションでインストールするFIRRTLファイル名を指定しています。



## テスト環境

- 安定バージョン
Stable Recent Version: 3.5.0
https://github.com/freechipsproject/chisel3/releases/tag/v3.4.0

- タグ情報
https://github.com/freechipsproject/chisel3/tags

- iotesters
iotestersは旧テスト用ツールです。
https://github.com/freechipsproject/chisel-testers/tree/master/src/main/scala/chisel3/iotesters

- tester2 (chisel-testers)
https://github.com/freechipsproject/chisel-testers
OpenCVforUnityのインポートとサンプル実行

UnityAssetStoreで公開されているOpenCVforUnityのimport手順です。
Sampleの実行まで行います。

環境は以下になります。
バージョン: Unity 2019.4.29f1
OS: MacOS Big Sur 11.5.2

[総コン Advent Calendar 2021](https://adventar.org/calendars/6691) 1日目の記事です。

#OpenCVとは
オープンソースのコンピュータビジョンに用いるライブラリです。
これを利用するとARや画像処理をするゲームを作ることができます。
今回インポートするのはUnityでOpenCVの各機能を扱えるようにするアセットです。

#AssetStoreからのインストール
適当なプロジェクトを作成します。
Window -> Asset Store をクリックして、AssetStoreビューを開きます。
検索窓に opencvforunity と入れて検索します。
![スクリーンショット 2021-11-30 16.22.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/28f5f18e-1529-5cd3-a73f-2b0020961481.png)
![スクリーンショット 2021-12-01 12.08.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/7b42a466-899f-3e12-a3f3-be402745f591.png)
購入してimportを押します。

![スクリーンショット 2021-12-01 12.50.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/29725076-19cd-2656-b048-ffb3c25d66bc.png)
こういう画面が出ます。(折り畳んでます。)
Sampleの実行をしない場合は、ExamplesとStreamingAssetsはチェックを外して大丈夫です。
Plubinsは各プラットフォームに書き出すためのものです。必要なものにチェックを入れてください。
チェックができたらimportを押します。
これでimport自体は終了です。

#Sampleの実行
![スクリーンショット 2021-12-01 12.20.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/bec6a20c-19c1-2fe0-4d34-8e1075e3395e.png)
OpenCVForUnityフォルダにあるStreamingAssetフォルダをAssetフォルダ配下にします。
![スクリーンショット 2021-12-01 12.24.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/94a55c46-d081-813e-e3f0-7208bdd3a509.png)
OpenCVForUnity/Examples/OpenCVForUnityExamples のシーンを読み込みます。
![スクリーンショット 2021-12-01 12.26.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/5eba25e0-aee6-4b99-b2c0-186f8ee60dba.png)
GameViewがこんな感じになると思います。

##BuildSceneの追加
![スクリーンショット 2021-12-01 12.27.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/8ea58309-8c3a-0e72-a04e-7292b589abfa.png)
File -> Build Settingsをクリックします。
![スクリーンショット 2021-12-01 12.31.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/d9264f87-63a4-6097-98d6-59152f29e0c1.png)
ここにSampleで読み込む全てのシーンを追加します。
##全Sceneの検索
![スクリーンショット 2021-12-01 12.30.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/024a9d52-7701-2b5f-57f6-9ad5dc5fe8d0.png)
検索窓に「t:Scene」と打つか、検索窓の右横にあるSearchBytypeボタンを押してSceneを選択します。
##全シーンをBuildSceneに追加する
![スクリーンショット 2021-12-01 12.33.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865650/3e3fbd17-4b5d-bb73-935f-02c44c6677e5.png)
先程の全シーンをcommand+aで全選択し、ドラッグ&ドロップでScene in Buildに追加します。
最後に再生ボタンを押して、実行できれば成功です。

#追記
毎年BlackFridayセールでこのアセットは半額で買うことができるっぽいです。
ちょっと待てばよかった……。
master以外からHerokuにpushした後、masterからHerokuへpushできない

## 直前に行った手順と遭遇したエラー
1. master以外のブランチ(issue1)からHerokuにpush
2. masterからHerokuにpush
3. 下記のエラーが発生

```bash
% git push heroku master               
To https://git.heroku.com/rails-portfolio-tyranno22.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://git.heroku.com/rails-portfolio-tyranno22.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```
これが原因と見られる

```shell-session
Note about fast-forwards
```
## エラー解決までの流れ
こちらの記事が「fast-forwards」についての理解を深めてくれました
[図で分かるgit-mergeの--ff, --no-ff, --squashの違い](https://sinsoku.hatenadiary.org/entry/20111025/1319497900)
つまり、デプロイ先のコミットの歴史（issue1）にmasterのコミット歴史が含まれていないからというのが本題でした。

```bash
$ git checkout master
$ git merge issue1
```

```bash
$ git push heroku master
```
問題なくpushできました

## 参考にした記事
- [master以外のブランチからherokuにpushする方法](https://qiita.com/fujiab/items/ca79dabad06bbd75ba39)
- [『 ! [rejected] master -> master (non-fast-forward) 』のせいでpushできねぇッ!!](https://qiita.com/hiroki-it/items/1671514eb659880e5bef)
OACを使ってHeatWave上のデータを分析できるハンズオンを作成しました

# はじめに
本記事は [Oracle Cloud Infrastructure Advent Calendar 2021](https://qiita.com/advent-calendar/2021/oci) の1日目です。

# この記事で伝えたいこと
OCI(Oracle Cloud Infrastructure)上で提供しているOAC([Oracle Analytics Cloud](https://pt.slideshare.net/oracle4engineer/oracle-analytics-cloud-20213))というBIサービスを使って、[HeatWave](https://www.oracle.com/jp/mysql/heatwave/)(※)上のデータを分析できるハンズオンを作成しました。HeatWaveやOACに興味がある方は是非試して下さい！！ハンズオンの解説動画も公開しています！！

※MySQLのマネージドサービスである[MySQL Database Service](https://www.oracle.com/jp/mysql/)専用のクエリーアクセラレーター。インメモリカラムナーデータベースで、超並列処理により高速に参照処理を実行できる。

# 本文
私のGithubで[HeatWaveのハンズオン](https://github.com/YoshiakiYamasaki/mysql-heatwave-workshop_jp)を公開しています。

Lab00～Lab07までを実行することで、HeatWaveを構成し、TPC-Hのサンプルデータをロードして、HeatWaveが無効な状態/有効な状態でのパフォーマンスを比較できます。

更にLab08では、小売業のサンプルデータをHeatWaveにロードし、OAC(Orale Analytics Cloud)というBIサービスからHeatWaveに接続して様々なデータ分析を試せる内容になっています。

ここまでの内容について解説した動画も[こちら](https://videohub.oracle.com/playlist/dedicated/170681322/1_2b7p6nie/1_0xrnnzn8)で公開しているので、HeatWaveやOACに興味がある方は是非試して下さい！！
XDキーボードショートカット｜ウィンドウ（ファイル）間の切り替え　

#そのままだとバグで使えない
AdobeオフィシャルのXDショートカット一覧には
下記のように記載されいる。

>ウィンドウ（ファイル）間の切り替え	⌘-チルダ（~）

https://helpx.adobe.com/jp/xd/help/keyboard-shortcuts.html

だが動かない。
USキーボードだから？と思ったが、家にUSしかないため未確認。
調べるとどうやらバグのよう。

動作確認環境
■ 2021年12月時点で割と最新のXD
■ MacOS10.15.7
■ USキーボード


#解決策はあった！


#### 1. システム環境設定を開く
キーボード＞ショートカット＞アプリケーション

![ 2021-12-01 12.33.59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168611/72c414cb-5367-1ba2-340a-8cd34b9dc286.jpeg)


#### 2.「＋」マークを押してXDを選択し、ショートカット追加

アプリケーション＞Adobe XD（出ない場合は「その他」から選択）


「次のウィンドウを操作対象にする」と入力して
キーボードショートカットの欄にカーソル置いてショートカットを入力で完了

Adobe公式と同じ⌘＋`が使いやすそうです。

![ 2021-12-01 12.43.31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168611/a1015457-0c56-900e-58e1-c7cdfa9534d1.jpeg)


ショートカットキーのバグとかトリッキーすぎるよAdobeさんよ。
VB.netで型をSelect Caseする方法

## はじめに
VB.netのジェネリック プロシージャなどで型で処理を分けたい場合がある
以下のようにしてすっきりと書きたいが上手くいかない。
```vb: これは使えない
Public Sub CheckType(Of T)(ByVal value As T)
    Select Case TypeOf value
        Case Integer
            Console.WriteLine("Type is Integer")
        Case String
            Console.WriteLine("Type is String")
        Case Else
            Console.WriteLine("Type is Other")
    End Select
End Sub
```

## Select Case True
ネットで調べると以下の方法をよく見つかるが、こんな書き方をするぐらいなら`If-ElseIf`でいいじゃないかと思う。(Select Caseで書くのメリットがない。。。)


```vb
Public Sub CheckType(Of T)(ByVal value As T)
    Select Case True
        Case TypeOf value Is Integer
            Console.WriteLine("Type is Integer")
        Case TypeOf value Is String
            Console.WriteLine("Type is String")
        Case Else
            Console.WriteLine("Type is Other")
    End Select
End Sub
```

## GetTypeを使う
`GetType`を使うことである程度すっきりと書ける
```vb
Public Sub CheckType(Of T)(ByVal value As T)
    Select Case value.GetType()
        Case GetType(Integer)
            Console.WriteLine("Type is Integer")
        Case GetType(String)
            Console.WriteLine("Type is String")
        Case Else
            Console.WriteLine("Type is Other")
    End Select
End Sub
```
もしくは
```vb
Public Sub CheckType(Of T)(ByVal value As T)
    Select Case GetType(T)
        Case GetType(Integer)
            Console.WriteLine("Type is Integer")
        Case GetType(String)
            Console.WriteLine("Type is String")
        Case Else
            Console.WriteLine("Type is Other")
    End Select
End Sub
```
C#でカノジョをつくる（1日目）

はじめまして。たなしょです。
ここ最近はPHPでWebサイトの開発保守を担当しています。
クリスマスまでにカノジョを作りたいと思います。
開発備忘録ですので所々文法の間違えがあると思います。ごめんなさい。

## なぜやるのか
クリスマスも近くなってきて「今年こそはカノジョと一緒にクリスマスを過ごしたい！」ということで、昨今の世間の事情や外になるべく出たくないという自分の性格も考慮して、エンジニアなので「プログラミングでカノジョを作ればいいのか！」と思い付きこの開発を始めることにしました。

## なぜC#なのか
仕事でもプライベートでもWindowsPCを使用している関係で、公私両方で彼女と会えるようにWindowsテスクトップアプリを作ればいいのではないのかと思い、「それなら一番簡単に作れるのはC#かなー」と思い付きでC#にしました。

## 方針など
この開発は3つのフェーズに分かれるのかなと考えています。
### フェーズ1
今までC#を触ったことがないのでまずは文法の確認に約1週間（12/8目途ぐらいで完了）ほど使おうかなと考えています。このフェーズでは以前C#をやろうとして1年以上本棚に眠っていた[スラスラわかるC# 第2版](https://www.amazon.co.jp/%E3%82%B9%E3%83%A9%E3%82%B9%E3%83%A9%E3%82%8F%E3%81%8B%E3%82%8BC-%E7%AC%AC2%E7%89%88-%E4%BA%94%E5%8D%81%E5%B5%90-%E7%A5%90%E8%B2%B4/dp/4798154636)を写経しながらC#の文法を身に着けたいと思います。

### フェーズ2
フェーズ1で使用した[スラスラわかるC# 第2版](https://www.amazon.co.jp/%E3%82%B9%E3%83%A9%E3%82%B9%E3%83%A9%E3%82%8F%E3%81%8B%E3%82%8BC-%E7%AC%AC2%E7%89%88-%E4%BA%94%E5%8D%81%E5%B5%90-%E7%A5%90%E8%B2%B4/dp/4798154636)を読み終わったら、[VisualC#](https://web-camp.io/magazine/archives/5302)を使ってデスクトップアプリを作っていくので前に本屋さんで立ち読みした際に、僕の作りたいものと同じ発想のものが書いてあった気がした[Visual C# 2022パーフェクトマスター](https://www.amazon.co.jp/Visual-2022-E3-83-91-E3-83-BC-E3-83-95-E3-82-A7-E3-82-AF-E3-83-88-E3-83-9E-E3-82-B9-E3-82-BF-E3-83/dp/4798066192/ref=dp_ob_title_bk)を読みながら作っていこうと思います。
かなり分厚い本なのでところどころ読み飛ばしながら進めていくかと思います。
このフェーズは約2週間（12/22目途ぐらいで完了）ほど使う予定です。

### フェーズ3
ここまで本に書いてあるソースを丸々コピーしているだけなので、ここから自分が考えた独自の機能を追加していくフェーズになります。
実際追加できるかどうかはわかりませんがコードの成形などできる限り何かしらやっていこうと思います。
このフェーズは残りの2、3日使って実施していく予定です。

## 最後に
だいたい平日1~2時間、休日2~3時間ほどは捻出できると思うので、25日間開発とブログを頑張りたいです。
ひっそりとやっていければなと思います。
目標ブラッシュアップ会の実施

[QualiArts Advent Calendar 2021](https://qiita.com/advent-calendar/2021/qualiarts)、3日目の記事です。
QualiArtsで開発ディレクターをしている、新見です。
QualiArtsのQUBEというチームで取り組んでいる、目標ブラッシュアップ会について紹介します。
QUBEについては以下の記事でも紹介しているので、是非読んでみてください。
[QUBEという取り組み](https://qiita.com/asakuranobuharu/items/15a82ea0017358207f37)

#期初目標設定面談と期末振り返り面談
QualiArtsでは半期に一度、プロジェクトマネージャーと技術評価者が同席をする目標設定面談と振り返り面談があります。

期初目標設定面談では、事前に立てた半期の目標に対して、以下のポイントを評価者とすり合わせします。

- プロジェクトの目指す状態と個人目標がシンクロできているか
- ミッションサイズは適切か
- 目線が低くなっていないか

期末振り返り面談では、期初に立てた目標に対して、実際にどのような成果を出せたのか自己評価をつけ、振り返ります。

#目標ブラッシュアップ会の実施と目的
QualiArtsでは一年前からエンジニア組織全体で目標ブラッシュアップ会を実施しています。
ブラッシュアップ会を実施した背景としては、以下のような状態を解決するためでした。

- 目標設定面談をする上で、事前に目標がしっかりと考えられていない。
- 自分が立てた目標に自信が持てない。
- 事前に壁打ちをする時間が確保できない。

半期の評価につながる目標になるので、そういった状態は解決するべきだと考えブラッシュアップ会の実施に至りました。

また、ブラッシュアップ会の目的を、以下の2点に絞って実施することにしました。

- 目標の精度を高める
- チームのみんなに目標を知ってもらう

エンジニア全員が閲覧することのできる目標集約シートを用意し、各自事前に目標を考えた上でブラッシュアップ会に臨んでもらうようにしました。
プロジェクトの各職種ごと3 ~ 6人のグループに分け、評価者がファシリテートをする形で、メンバーの目標のブラッシュアップを行ってもらいました。その際、メンバーからも目標に対して意見やアドバイスをしてもらうような形で実施しました。


#実施後のアンケート
実施後にアンケートをとりました。
回答者全員が、ポジティブな回答でしたのでどのような意見があったのかを一部紹介します。

- 他の人の目標を見る機会が少なかったのでとても参考になった。
- 先輩の目標を知る機会がなかったので、凄く参考になった。
- 多くの先輩方とすり合わせることにより、今後どのように動いていくかがより明確になった。
- 普段意識することのない、メンバーの目標を知るよい機会になった。
- 技術評価者以外のフィードバックがあるのが嬉しかった。
- チームメンバーに宣言が出来るいい機会になった。
- これまでは面談前にフィードバックをもらう機会がなかったので良かった。

これは、個人的な意見ではありますが、対プロジェクト目標以外にも、横軸活動、組織活性化、若手の育成など普段一緒に仕事にしているだけではなかなか見えない部分の目標をチームのメンバーに知ってもらえたのはとてもよかったのではないかなと感じています。
また、先輩が若手の目標を把握することはあっても、若手が先輩の目標を把握することはこれまでなかったので、先輩の目標を知ることで自分の目標設定に役立てることができるというのは、非常に効果的だったと思います。

実施後のアンケートで、ブラッシュアップ会だけではなく振り返りをする場も設けて欲しいなどの意見を多数いただいたので、現在ではエンジニア組織全体として振り返り会の実施もしています。

#まとめ
今回は、QualiArtsでの目標ブラッシュアップ会という取り組みを紹介しました。
ブラッシュアップ会は一年前から取り組んでいる施策であり、目標設定や振り返りに関する施策自体のブラッシュアップはまだできる余地はあると考えています。
よかったポイントは継続しブラッシュアップを重ね、上手くいかなかったポイントはやめるといった形で、より施策自体も良いものに変えていけたらと考えています。
今後もQUBEでは、「エンジニアの成長が加速し、継続的に事業成果があげられるエンジニア組織」というミッションの実現のため色々取り組んで行こうと考えています。
今後の取り組みについても、機会があれば皆様に紹介していきたいと思います。
最後まで読んでいただいてありがとうございました。
IT D☆O★K☆A★T☆A★ 2021年を振り返る

# この記事は
今年自分にとってどんな一年だったかを振り返っておく記事です。

# 2021年振り返り
今年は転職して分野が少し変わったので、技術的なギャップがあったために、インプットが多い一年だった気がします。(全部流れ出ていったが...)   

## 転職
転職のきっかけは、たまたま前の上司に~~拉致られた~~誘われたのがきっかけでした。
いわゆるリファラル的なカジュアル面談で、とても熱い思いを語る姿をみて、筋肉の話のしかしてなかった人がどうしてしまったのか？と疑問に思い人をここまで変えてしまう会社に魅力を感じて転職を決めました。

実際に転職後は、やっぱり筋肉の話がメインで一安心しました。   

転職先では、データ関連のシステムを触っています。
私は、約10年(もう10年、、、、)ぐらいtoC系のサービスのサーバーアプリケーションのエンジニアとしてほとんど過ごし、途中2年ぐらいデータ関連のシステムに携わったことがあるどこにでもいる吹けば飛ぶような場末のエンジニアです。

2年半ぶりぐらいにデータ関連のシステムを触ることになったのですが、だいぶ様変わりしている印象を受けました。

もともとprivate cloudで諸々のシステムを運用するような会社にほとんどいたので、public cloudをガッツリ使うのも初めてっていうのもあり、老害おじさんは、ついていくのでアップアップしています。

### データ関連のシステムをやることについて
こういったシステム触ると思うことですが、データを集めてこねくり回すって現代の会社にとって、とっても大切な気がしますが実際には後手後手になりやすく、人も集まりにくい、データ量がかさむから予算は右肩上がり、更に分野の進化が早くマイグレーションも大変と結構と、これだけ並べるとただの3kみたいな感じになりますが、ドＭ気質なところもあるからか結構面白かったりします。

### 転職してよかったか？
結果よかったなーと思っており、文化やチームの雰囲気が、今の会社がほうが合っている気がしてそこがよかったなと思っています。(別に前の会社が悪いっていうわけでない)

## 仕事用の椅子と机を買った
腰や肘が痛くなってきたので、机と椅子を買いました。
gtracingのゲーミングチェアとゲーミングデスクを２つ合わせて25000円ぐらいでとりあえず揃えた感じです。

社内では、アーロンチェアとか景気のいい話が聞こえましたが、家庭では、つば九郎並の待遇しか得られていない私には、そんな高級品を大蔵省から決済をもらうのは、至難を極めたので、家電量販店に置いてあったゲーミングチェアとデスク(共にakraging)を嫁にレビューしてもらい「前見た椅子と机の安いバージョンあるんだけど」とドア・イン・ザ・フェイスを実行し密林で購入しました。

嫁には、「痩せろよデブ」とキレられましたが、結果的には、非常に満足の買い物だったと思います。

## まとめ
転職っていう段落を作ったが、転職しか主だったイベントがなかった2021年でした。
気づけば、来年はエンジニア10年目なので、なんかしようかな、、、(転職ではない)
あとは、腰や肘に支障をきたすレベルのデブという認識を持てたので、痩せようと思いました。
【javascript】Storage

# Storageブラウザの保存領域にデータを格納するためのオブジェクト


# 保存と取得
* データは同期的に保存される。

```js

localStorage.setItem('key', 'value'); //保存

const result = localStorage.getItem('key');　//取得
console.log(result)

//json形式で保存
const obj = {"a": 1, "b":2};
const json = JSON.stringify(obj)
localStorage.setItem('json', json)
const json_result = localStorage.getItem('json')
console.log(json_result)

>>> {"a":1,"b":2}
```

# データの確認

ブラウザの検証ツールからapplication > localstrageでkey,valueで保存されている。
その他メソッドは、`__proto__`に格納されているので随時確認してみる。
JSONとは

# JSON
表記はjavascriptのオブジェクトに似ているが、JSONはオブジェクトではなく文字列になる。

## JSONの変換メソッド
* JSON.parse
    * JSON　=> Objectへ変換
* JSON.stringify
    * Object => JSONへ変換


```js

const obj = {a: 0, b: 1, c: 2};

const json = JSON.stringify(obj)
console.log(typeof json)

>>> string


const obj2 = JSON.parse(json)
console.log(typeof obj2)

>>> object
```

ストレージなどにデータを保存する場合はJSON形式になるので変換メソッドはよく使う。
COALESCEでnullを任意の値で返す

#COALESCEの使用場面
nullの値がある場合、代わりの任意の値で出力したい場面があると思います。
このような場合、COALESCEという関数があることを知りました。
今回は業務の中で、null値を0で出力する必要がありましたので備忘録として残します。

##null値を含むデータを用意
今回はcustomersテーブルを用意し、以下のカラムを設定しました。
・id(自動連番)
・name
・phone1
・phone2

それぞれ、phone1とphone2にnull値を用意しています。
これらを任意の値(今回は0)で出力します。

```
select * from customers;
```

![スクリーンショット 2021-11-30 17.54.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321039/916951da-7a33-84c6-5cc8-3a0add0cb523.png)

```
select id,name,coalesce(phone1, 0) as phone1,coalesce(phone2, 0) as phone2 from customers;
```

![スクリーンショット 2021-12-01 9.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321039/76d6078e-1e5a-dd46-3abf-12458282f837.png)

画像の通り、null値を0で出力することができます。
実務では他にも、null値を"不明"として集計するなどに活用でそうです。上記の例でしたら、customersテーブルのnameカラムがnullの場合、'不明'と出力する等々などです。
Twitterに誰でもドット絵を投下できるサービスを作ったよ

どうも今年もやってきました [クソアプリアドベントカレンダー](https://qiita.com/advent-calendar/2021/kuso-app) 1の2日目を担当させていただきます [@nabettu](https://qiita.com/nabettu) です。
今年で参加５年目らしい。まじかよ。

## 過去のクソアプリ達

https://qiita.com/nabettu/items/dfa3350d58831125045f

https://qiita.com/nabettu/items/ba2081d48b8cafa13f12

https://qiita.com/nabettu/items/4670a79c429a4eb70b62

https://qiita.com/nabettu/items/331e16d7963d8433f1ca

## 作ったもの

今年作ったのはこちら！

https://100pixelart.nabettu.com

100 Pixel Artというドット絵が書けるWebサービスです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40154/ccb321fc-9c35-cb32-c597-98307bac7f12.png)


## どんなサービスか

絵文字の ⬜ 🟥 🟧 🟨 🟩 🟦 🟪 🟫 ⬛ の９色の四角のみを使ってドット絵が描けるサービスになります。

10かける10で100ドットのみ9色限定で、9^100パターンのみ作れるエディターになっております。

キャンバスサイズが100ドットのみで、使える色も9色しかないというポイントがクソアプリ的制限です！

## サービスの特徴

このサービスの特徴として「Finish」ボタンを押すと、編集が完了すると**絵文字なのでそのままテキストとしてコピーできます**。

つまり完成したらそのままTwitterでテキストとしてつぶやくことができるんです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40154/5cbed265-7356-ce25-045e-665bea8f1668.png)


画像としてどこかに保存しなくていいし、そのままシェアできて便利ですね〜。。。

（あれ、、、思ったより全然クソアプリじゃないかも、、、）

## 技術的な話

- React（ルーティングとかないけどNext.jsを使うだけ使っています）
- Cloudflare Pages

Cloudflare Pagesめちゃめちゃ便利なのでみんな使うと良いと思います！Netlifyがアジアリージョンなくなって悲しんでいた方におすすめです。

https://pages.cloudflare.com/

## 苦労したポイント

表示はCanvasを使わずにDomでやっています。

ドットをクリックして絵文字が切り替わるのはonClickで設定するだけなのですが、ドラッグしてもちゃんと絵文字が反映されるようにするのがちょっと工夫が必要でした。

### PCの場合：マウスでの動作について

- キャンバス上でクリックダウンされたらフラグをON
- マウスがクリックアップされたらフラグをOFF
- キャンバスからマウスカーソルが外に出たらOFF
- キャンバス上でフラグがONの状態でドラッグされていたら文字を変える

という形で実装できました。

### スマホの場合：タッチでの動作について

基本のタップはPCと同じ形にしておりますが、タッチしながらの移動（タッチムーブ）は同じ実装では動きません。

タッチムーブではイベントがタッチし始めのdomから発火してしまうので、

1. タッチムーブで別な要素への移動を検知
2. 移動後の座標を確認
3. キャンバス全体からの相対座標で10*10の中のどこにいるかをチェック
4. その座標の位置の文字を変える

というちょっとした計算を追加して実装しました。

（・・・素のJSで作ってしまったのでライブラリ探してもよかったな！笑）

### Androidでは四角のカラー絵文字が無い

これは困ったのでNoto Color Emojiを入れました。

※ [Apache 2.0ライセンス](http://www.apache.org/licenses/LICENSE-2.0) です。

以上です！

クソアプリアドベントカレンダー2021 二日目、100 Pixel Artでした！

https://100pixelart.nabettu.com

明日は@alclimbさん「2021年×おバカアプリ✨」なクソアプリをよろしくお願いします！
【PHP】インターフェースについて

自分が今参画している案件でインターフェースを記述している場面を見かけたので、
メモしてみました。

```php
<?php
  interface インターフェース名
  {
      public function findById(int $id): userEntity;
      public function findByIds(array $ids): array;
  }
  class UserController implements インターフェース名
  {
      public function findById(int $id): userEntity
      {
          // 取得処理
      }
      public function findByIds(array $ids): array
      {
          // 取得処理
      }
  }
```
インターフェースで記述できるのは「publicな関数のみ」です。
protectedやprivateなものは書くことができません。
あくまでも「この関数があるよ」という「宣言」のみの記述です。

クラスでインターフェースを採用する際には、`implements`を使用します。
なんとなくわかりますが、コードの記述量も増えることからどういったメリットがあるのでしょうか？

```
interfaceに記述されている関数が、interfaceを採用しているクラスで利用されていないとエラー表示してくれる
--> 関数の記述漏れを防ぐメリットがある。

インターフェイス内の関数が用意されていることが保証されている。そのため、クラスの関数をあらかじめ把握しやすくなる。
--> インターフェイスはある特定の関数群の概要を記述したものなので、クラスの仕様書みたいな使い方もできる。
```

それに付随するインターフェース を利用したDIについては、また時間ある時にまとめます...
Vue Scoped Slotで親から子のメソッドに引数を渡し発火させる

[パーソンリンク アドベントカレンダー](https://qiita.com/advent-calendar/2021/personlink)5日目です！🎉

# 環境
Vue.js2系

# きっかけ
slotする親からVueコンポーネントに情報伝達がしたいケースがありました。
slotする内容でなければemitすれば良いだけの話ですが、このケースはそうはいきません。

具体的にいうと、slotしたDOM内のbutton要素がクリックされた時、
子コンポーネントのイベントを引数を渡して発火させたかったのです。

## 親コンポーネント
```html
<sample-component>
  <form>
    <input type="text" id="keyword>
    <button v-on:click="clickEvent(data)">実行</button>
  </form>
</sample-component>
```

## 子コンポーネント
```vue
<slot v-bind:on="slotOn"></slot>
```

```javascript
function slotOn(data) {
  // dataを受け取り何らかの処理
}
```

# 対処結果
この場合は、scoped slotとactivatorを使います。

## 親コンポーネント
```html
<sample-component>
  <template v-slot:activator="{ on }">
    <form>
      <input type="text" id="keyword>
      <button v-on:click="clickEvent(on)">実行</button>
    </form>
  </template>
</sample-component>
```

```javascript
function clickEvent(on) {
  return on(data);
}
```

## 子コンポーネント
```vue
<slot name="activator" v-bind:on="slotOn"></slot>
```

```javascript
function slotOn(data) {
  // dataを受け取り何らかの処理
}
```

こうすることで、slotの内容で発火するイベントから、子コンポーネント内の `slotOn` 関数を発火させ、尚且つ引数も渡すことができます。

# 解説
## activator
`v-slot:activator`は名前付きスロットの書き方です。
`activator`という名前のスロットを作成しています。

では`v-slot:activator="{ on }"`は何をしているのでしょうか。

これは、スロット`activator`から`on`というプロパティを取得して、
プロパティ`on`を`on`という変数名に代入しています（分割代入）。

そして`on`の中身は、この例で言うと子コンポーネントで指定したslotOnメソッドになります。

```javascript
function slotOn(data) {
  // dataを受け取り何らかの処理
}
```

## Scoped Slot
これらの機能を実現するのがVueのScoped Slot(スコープ付きスロット)です。
親コンポーネント内でスロットコンテンツとして子コンポーネントからプロパティを使えるようにするには、
`slot`要素の属性に使いたいプロパティをバインドします。

```vue
<slot name="activator" v-bind:on="slotOn"></slot>
```

`slot`要素にバインドされた属性は**スロットプロパティ**と呼ばります。
親スコープ内で`v-slot`の値として名前を指定することで、スロットプロパティを受け取ることができます。


# 参考
[スコープ付きスロット](https://jp.vuejs.org/v2/guide/components-slots.html#%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E4%BB%98%E3%81%8D%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88)
[v-slot:activator="{ on }"の仕組みの考察](https://qiita.com/aotoriii/items/06ae49c135061a12b75e)
転職ドラフトで業務委託を勝ち取るまで

# 転職ドラフトとは

https://job-draft.jp/
オファー型の転職サイトです。
オファーの段階で契約の金額が提示されるので、給与を基準に会社を探している私はとても重宝しています。
また、利用していると自分の市場価値も見えてくるのでおすすめです。
最近では業務委託形式のオファーも可能になっており、転職はしたいものの正社員かフリーランスかで迷っていた私にはぴったりなサービスでした。

# 登録したきっかけ

新卒で入社した会社の上司が転職することになった時に、どんなサービスを使っていたのか聞いたらこのサービスを教えてくれました。
それからかれこれ4~5年経つと思いますが、ずっと利用しています。

# 指名状況

毎月ドラフトが開催されており、参加/不参加 を選べるのですが参加した時には必ず1社以上はオファーをもらえています。
メガベンチャーからスタートアップまで色々な会社からオファーをもらえます。
オファーをもらえると、自分を必要としていることが感じられて毎回とても嬉しい気持ちになります。笑

# 面接で感じたこと

とはいえ面接で「俺が必要なんだろ？」みたいに上から目線で行ってしまうとうまくいきません。
面接は普通の転職で面接を受けるのと同様の心構えで行くのが吉です。
会社にもよりますが、少なからず必要としてオファーはしてくれているはずなので、普通の転職の面接よりはウェルカム感は感じます。

# 転職ドラフトへの改善要望

非常に魅力的なサービスで、UI/UX も満足していますが、まだまだ参加企業が少ないとは思うので、そこが今後どんどん増えていくことに多い気に期待しています。

# 転職ドラフトを使ったことがない方へのメッセージ

企業からのオファー数や年収で自分の市場価値がわかるので、転職を検討している人が試しに登録するのにも向いています。
給与を基準に転職をしたい人は転職ドラフトを使えば「時間をかけて内定をもらったけど年収に納得がいかない」というような時間を無駄にすることがないので非常におすすめです。
転職の際は複数のサービスを使うことがスタンダードだと思うので、そのうちの1つとして使うことを是非お勧めします。


（こちらの記事は転職ドラフト体験談投稿キャンペーンに参加しています）
https://job-draft.jp/articles/251
【初心者向け】MechanizeでJavaScriptの箇所を読み取れない

###■環境
・Windows10(64bit)
・Ruby 2.7.4
・Rails 5.2.6
・Mechanize 2.8.2
###■MechanizeでJavaScriptの箇所を読み取れない
####状況
Railsアプリケーションでgem「Mechanize」を使用し、Webスクレイピングを行っている。
しかし、HTMLファイル内のJavaScriptの箇所だけ読み取れない（パースできない）。
####原因
MechanizeはJavaScript未対応
####対処1
MechanizeではなくSeleniumなどを使用

https://iwathi3.hatenablog.com/entry/web_scraping_Ruby_Selenium

####対処2
JavaScriptが行うはずの処理をRubyで置き換える。
ただし、そのためにはJavaScriptの内容を読み解く能力が必要。

https://www.ownway.info/Ruby/mechanize/against_javascript

####対処3
HTMLファイル内のscriptタグを削除し、読み取り可能になるか試す。

```ruby:例
# Mechanizeの初期設定を実行。Mechanizeクラスのオブジェクトを作成。
agent = Mechanize.new
# 保持する履歴の最大数を指定。「0」だとリファラー周りで不都合があるが、大きいとメモリ容量を取るため、「2」辺りが妥当。
agent.max_history = 2
# HTTPリクエストのヘッダーにUser-Agentを設定。指定文言以外だとMechanizeの情報が送信されてしまうため注意。
agent.user_agent_alias = 'Windows Mozilla'
# キャッシュに存在するページへの再アクセス時に更新チェックを行うかどうかを設定。true：変更が無ければキャッシュを再利用。
agent.conditional_requests = false

# URLを取得
top_url = 'https://sample.co.jp/'
# MechanizeにてURLからHTMLファイルを取得し、パースを阻害するJavascript関連のタグを削除。
html = agent.get(top_url).body.gsub!(/<script.*?>/, "").gsub!(/<\/script>/, "")
# 以降で必要なパースなどを行う
```

・Mechanizeのgetメソッド：　URLが表すページを取得する
・Mechanizeのbodyメソッド：　ページのBody部を返す
・gsubメソッド：　文字列を置換する。標準では非破壊的メソッドのため、今回は「!」を付け破壊的メソッドにしている。

https://seesaawiki.jp/ruby_mechanize/d/Mechanize
VPN完全に理解した

##はじめに
この記事は[「完全に理解したTalk Advent Calendar 2021」](https://qiita.com/advent-calendar/2021/easyeasy)3日目の投稿記事です。

>完全に理解した、それはまさに「分かった気になったくらい」の理解できたくらいのもの！ 
「覚えたての知識」や「この知識なら自信出てきた！」みたいなものから「あれ、ちょっと怪しいかも？」となり始めた知識まで自分が話したい知識をなんでもゆるーく話をしてみませんか！
みんなにOUTPUTして、是非自分の実力を高めちゃいましょう！

ゆるくてもOKとのことなので、記事を書きました。

##テーマ選定のきっかけ
在宅勤務時、VPN接続で会社のサーバーにつないでいます。
(在宅勤務の話をするのも今更感はありますが)

VPNをよく知らないまま便利なツールとして使っていたので、少し勉強しようと思ったのがきっかけです。

##VPNとは
「**V**irtual **P**rivate **N**etwork」の略で、仮想専用線という意味になります。名前の通りインターネット上に仮想の専用線を敷くことで、各拠点間でのやりとりを可能にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/712213d9-dbce-5b1e-e2bb-d6444841ed32.png)

イメージを図にしてみました。インターネット上に専用のトンネルを設け(トンネリング)、やり取りするデータはロックすることができます(暗号化)。
受信したデータは予め決まった鍵でロックが外れ、やり取りが可能になります(承認)。
ロックに対応する鍵は、正しい送受信者しかわからないため比較的安全に情報を取り扱うことができます。

###専用線との違い
まずはイメージから。

<dt>VPN</dt>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/97c4855e-f7ec-525d-32e0-8e8e273030bc.png)

<dt>専用線</dt>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/5ed10f54-b1ac-51ec-c15d-ee98c7cbd022.png)

専用線は拠点と拠点を1対1でつなぐ必要があり、同じ線で複数の拠点同士を結ぶことはできません。
(VPNでは空のように連続になっているので、トンネルをバコッっと置けば複数拠点の接続が可能)

安全性はVPNより高くなる分、設置コストの負担が増えてしまう欠点があります。

##VPNの種類
###1.インターネットVPN
既存のインターネット回線を利用したVPNです。最初に挙げたイメージ図に近いのではないかと。
元々ある環境を使えるので、コストが安価になるメリットがあります。ただし他のVPNに比べて安全性に不安は残ります。

###2.IP-VPN
通信会社が提供する閉域網を使う方法になります。インターネットからは切り離されており、通信業者と契約者のみが利用できます。コストはやや高くなり、またネットワーク設計のカスタマイズは制限があります。
⇒インターネットが空ならば、閉域網は地面のイメージ。地面を掘ってトンネルを作る方が、空で領域を区切るより入りにくいはず(少なくとも自分の考えでは)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/a60f9592-af59-a67f-fffd-5d12a5861359.png)

###3.広域イーサネット
通信会社が提供する閉域イータネット網を使う方法になります。IP-VPN同様、インターネットからは切り離されています。IP-VPNよりもネットワーク環境のカスタマイズが可能になります。ただしその分費用もかかったり、設定が複雑になったりします。
⇒もっと鍵をかけたり、暗号化のレベルを上げたりなど。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/8149917f-7307-6e3f-33ad-d6e28568e58c.png)

###4.エントリーVPN
安価な光回線を使って閉域網に接続する方法です。インターネットVPNとIP-VPN(広域イーサネット)のいいとこどりです。コストが安く、なおかつセキュリティもそれなりに高いレベルになります。
ただし通信速度は遅くなる場合があります。
⇒つながっている線がもっと細いイメージ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/65f94791-31d7-4ef7-a762-406b26f52884.png)

##まとめ
違いが分かるようになるべく頑張って図にしてみました。
VPNの種類が分かったから、「完全に理解した」にしてます！
VPN「チョットワカル」な人は、VPNのプロトコル記事も参照につけてますのでご覧ください。


##参照
* VPN全般

[ICT Digital Column](https://www.nttpc.co.jp/column/network/whats_vpn.html)
[ＪＢサービス株式会社　お役立ちブログ](https://www.jbsvc.co.jp/useful/security/vpn-connection.html)
[MCore](https://www.sei-info.co.jp/mcore/basics/vpn.html)
[アイティーエム株式会社](https://www.itmanage.co.jp/column/about-vpn/)

* プロトコル

[NETMOTION](https://www.netmotionsoftware.com/ja/blog/connectivity/jpn-5-vpn-protocols#)
[YAMAHA](https://network.yamaha.com/knowledge/vpn/protocol)
Google検索と仲良くなる！プログラマー必見ググラビリティについて


どうも初めまして。エンジニアのあーみーです。

私自身教育を担当している立場という事もあって、新人コーダーや新人エンジニアさんの質問に答える機会が割と多いのですが、
新人さんが躓きやすいGoogle検索についての記事を書かせて頂きました。

是非最後までお読み頂けますと嬉しいです 🥰


# 1. ググラビリティとは

俗に言う「検索力」です。

今回は目的のページに辿り着くというのもそうですが、Googleないしインターネットを用いたトラブルシューティングについて解説したいと思います。

## 2. 検索の前にすること

まず大前提としてエラーが発生した際は**すぐにGoogle検索を利用してはいけません。**
基本的にエラー構文を読む事が大事です。
これをやっていないエンジニアさんが大半です。

※今回は簡単な例題にしています。
また言語はjsを利用します。

```js:
const hogehoge = 1;
hogehoge = 'text';
```
こんな感じの誰でも分かるレベルの不具合を書いてみましょう。
その際のエラーはこんな感じです。

```
Uncaught TypeError: Assignment to constant variable.
    at index.js:2
```
プログラマーだとしたら行数を見たらすぐに間違いに気づきますが、経験が少ない方だとそうはいきません。
まずはエラーの内容を読む事が大事です。
英語が苦手な人は[Google翻訳](https://translate.google.co.jp/?hl=ja)や[DeepL](https://www.deepl.com/ja/translator)を使いましょう。

```
Uncaught TypeError：定数変数への割り当て。
     index.js：2で
```
翻訳を掛けると嘘みたいに答えを教えてくれます。
これを読んで理解できなかったら基礎が出来てない証拠です。
その場合は振り返って学習しましょう。上記の例だと定数変数に割り当てをした結果エラーが発生したというのが原因でしょうか。

翻訳したら出てくる答えのパターンでも理解できない・躓いてる人は以下のパターンに該当すると思います。

* 答えが出ているのに気付かない。（読み込めてない）
* 答えの意味が理解できない。（基礎知識が低い）
* Google検索すれば出ると思い込んでる（思考停止）

まずはエラー構文を読みましょう:v:


## 3. 検索してみる

エラー構文を読んでも理解が出来なかったら、**そのままの文章で検索しましょう。**大事な単語が欠けてたりするとGoogleは意図した言葉を出しません。（まれに出しますが）
なので`Uncaught SyntaxError: Invalid or unexpected token`等のエラーが発生した場合はそのままの文言で検索しましょう。

## 4. プログラミング側の気持ちを掴む

大前提として〇〇を作りたいと思うエンジニアの思考とソースコードをただ実行しているプログラミング言語の思考は全然異なります。
恐らく「エラー読んでも分からない！」という人はここのコツが掴めていないのかなと思います。

説明してもアレなので例文を作りました。
実用的なソースを用いて説明します。

```js
const requestApi = async () => {
  const res = fetch('/data.json');
  const body = res.json();
  console.log(body.user);
}
requestApi();
```

特定のデータの中身をリクエストして、ログを出力するというものです。
このソースを実行すると下記のエラーが表示されます。

```
Uncaught (in promise) TypeError: res.json is not a function
    at requestApi (index.js:5)
    at index.js:9
```
先程挙げたエラー構文をそのまま読むと`res.json is not a function`がヒントになってくれそうな気がしていますが、[fetchAPIのドキュメント](https://developer.mozilla.org/ja/docs/Web/API/Response)には戻りのオブジェクトに関数：jsonが存在しています。

じゃあ何故エラーが`res.json is not a function(res.jsonは関数ではありません。)`と表示されるのでしょうか。

考えられるエラー解決の思考の流れは下記のようになるのが最適解かなと思います。

* res.jsonが関数ではない別の何かになっている
* resはそもそも何だろう？
* そもそもfetchの使い方は正しいのか？

この流れでいけばどんな言葉で検索するのか分かりますか？
そうです、「fetch javascript」で検索してみましょう。

出てきた最初のURLの[mozillaのサイト](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options)に記載がありました。

※以下引用

```js
// POST メソッドの実装の例
async function postData(url = '', data = {}) {
  // 既定のオプションには * が付いています
  const response = await fetch(url, {
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin

```
使い方の例を見ると`await fetch`とawaitするのが正しかったようです。
これも基礎が抜けていたという結論で終わるのですが、初心者の方自身は基礎が出来てるか否かはやってみないと分かりません。
その為の解決方法で上記のような思考回路が必要になってきます。

とどのつまり、**エラー文章を読んでも参考にならない**という人はこのような検索までに至る思考が形成されていないケースが大半かなと思います。

なのでエラー文そのままで検索しても答えに辿り付けない場合、**エラーの結果だけ見るのではなくて、エラーに至った過程を想像してみましょう。**

結果だけ見てその場しのぎの対応を繰り返すとあなたのコードがいとも簡単にクソコードと化します！！ご注意あれ！

## 5. さいごに

簡単に説明させて頂きましたが、何かありましたらご意見いただければ幸いです。
それではみなさんHappy Hacking!
[CentOS7] 古いバージョンのApacheとPHPを連携するまで

:::note warn
警告
この記事は、前回の記事 を読んだ前提で書いてます。
ご了承ください
:::

[リンク](https://qiita.com/Marny/items/3824eca3b3194ba37f30)

# はじめに

この記事は[[CentOS7]Apacheの古いバージョンの導入とデーモン化](https://qiita.com/Marny/items/3824eca3b3194ba37f30)の続きです。

Apacheインストール終わったけど、PHP使いたくてもできない！！！！！

ってことで一日使いました。無念。。
てか、デフォルトでできない分、普通の設定だとうまく動きません。なので、発生したインシデントと対応についてつらつら書きます。


# 経緯

先日上げた[記事](https://qiita.com/Marny/item/3824eca3b3194ba37f30)では、Apacheのインストール・デーモン化を行いました。
ウッキウキな僕はおもむろにPHPを記述。
Apacheを起動！
ブラウザで確認！！！

何も出ない。

\omg/


yum で PHPをインストールしただけだと、もとからあるApacheに設定を吸われるっぽい（そりゃそう。）

ってことで気合でどうにかしないといけません。


# やったこと

- デフォルトのApacheの設定ファイル（httpd.conf）を見に行く
→/usr/local/apache2と比較するため
→よくわからん

- 「Apache PHP」と検索して一通り試す
→動かない

うーん困った。。。

とりあえず、PHPinfoを出したい、、、
PHPinfoはコマンドライン上では見える。ブラウザでは見えん。ってかPHP動いてないし、なんかダウンロードされるし。

# 解決策

困ったのでデフォルトのApacheのmoduleを見に行きました。場所はfindコマンドとかで探して。

どうやらPHPのモジュールがあってそれをうまく読み込めていない状況。

```:httpd.conf
<IfModule !mod_php5.c>
  <IfModule prefork.c>
    LoadModule php7_module modules/libphp7.so
  </IfModule>
</IfModule>


<IfModule !mod_php5.c>
  <IfModule !prefork.c>
    LoadModule php7_module modules/libphp7-zts.so
  </IfModule>
</IfModule>
```

とりあえずこの辺をコピペ。

なんかびみょー

色々調べる。ふむふむ。

とりあえずできたコピペをこちらに

```:/usr/local/apache2/conf/httpd.conf
<Files ".user.ini">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
        Satisfy All
    </IfModule>
</Files>

AddType text/html .php

DirectoryIndex index.php

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>


AddHandler phpX.X-script .htm .html

<IfModule !mod_php5.c>
  <IfModule prefork.c>
    LoadModule php7_module modules/libphp7.so
  </IfModule>
</IfModule>


<IfModule !mod_php5.c>
  <IfModule !prefork.c>
    LoadModule php7_module modules/libphp7-zts.so
  </IfModule>
</IfModule>
```
そうそう。この`LoadModule`ってとこのmoduleは一応コピーしないとってことで、

```
cp -p /usr/lib64/httpd/modules/libphp7.so /usr/local/apache2/modules/
cp -p /usr/lib64/httpd/modules/libphp7-zts.so /usr/local/apache2/modules/
```

これでいけた。僕の場合。

あと、`httpd -tS`ってコマンドが`httpd.conf`のエラーチェックなのでいっぱい使う。

## なんか動かない場合（参考にならないかも）

前述しているように、デフォルトで入っているApacheがあります。`httpd -tS`コマンドを混在しないように消します。

```
sudo yum remove -y httpd apr apr-util httpd-tools
```
そうすると、デーモン化したApacheが動かなくなるので、再度`make install`してあげてください。

そうすれば、`systemctl`から起動できると思います。

# PHPファイルがダウンロードされるんだけど！
これはまじで糞だった。

意味わからんし。

まぁさっきの`httpd.conf`で治ったんだけど、一応使っているブラウザのCookieを削除しておきましょう。
多分治るはず。
WordPressプラグインの翻訳が更新できない対処（成功）

[作業環境](#作業環境)
[不具合](#不具合)
[パーミッション確認](#パーミッション確認)
[rootをapacheに変更する](#rootをapacheに変更する)
[更新の確認](#更新の確認)
[プラグイン更新](#プラグイン更新)
[参考記事](#参考記事)

#作業環境
`centos 7`
`php 8.0.13`
`WordPress 5.8

#不具合
`all-in-one-wp-migration-ja翻訳が更新できません。パーミッションが関係している場合があります`

#パーミッション確認

```
# ls -l /var/www/html/example.com/wp-content/languages/plugins

-rwxrwxr-x root root 40867 12月  1 11:24 all-in-one-wp-migration-ja.mo
-rwxrwxr-x 1 root root  54823 12月  1 11:24 all-in-one-wp-migration-ja.po
```

#rootをapacheに変更する

```
# chown -R apache:apache /var/www/html/example.com/wp-content/languages
```

#更新の確認

```
# ls -l /var/www/html/example.com/wp-content/languages/plugins

-rwxrwxr-x 1 apache apache  40867 12月  1 11:24 all-in-one-wp-migration-ja.mo
-rwxrwxr-x 1 apache apache  54823 12月  1 11:24 all-in-one-wp-migration-ja.po
```

#プラグイン更新

成功した

***
#参考記事
`https://wp-doctor.jp/blog/2020/04/14/%E3%83%AF%E3%83%BC%E3%83%89%E3%83%97%E3%83%AC%E3%82%B9%E3%81%A7%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF%E6%A8%A9%E9%99%90%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A8%E3%83%A9/`
greple #1 イントロ

# はじめに

## greple

greple は、作者が1990年初頭から開発を続けているコマンドです。名前の通り Unix コマンドの grep と同じように、テキストから文字列を検索するためのコマンドラインツールです。le は lexical expression の意味ですが、それについてはこれからおいおい説明していきます。

## 読み方

読み方は特に決めていませんが、なんとなく「ぐれっぷる」と呼んでいます。アクセントは「れ」にあったり、今時の平板化した読み方だったりと、人によって様々です。英語的に発音すると「ぐれぽー」みたいになるんでしょうか。

「ぐれっぷ・えるいー」と読んでもいいけど、長いですね。アメリカ人、なんでも単語化しようとしますしね。SCSI が「すかじー」になるくらいで。昔、PCMCIA を無理やり読んでいる人がいて驚いたことがあります。

## 特徴

greple は、以下のような特徴を持っています。

- 複数のキーワードを指定できる
- 行だけではなく、検索対象ブロックを柔軟に指定できる
- 検索対象の範囲や条件を指定できる
- 複数行に渡るパターンを検索できる
- 多彩な色指定が可能
- 設定ファイルやモジュールによるカスタマイズ／拡張が可能
- 単なる検索だけではなく、文字列処理のフレームワークとして機能する

これらの特徴や使い方について、これから毎日少しずつ解説していこうと思います。

## 想定される用途

元々、文章の校正作業を楽にするために作ったもので、その後もまとまった翻訳の仕事が入る度に少しずつ拡張を続けてきました。そのため、それほど多くないテキストファイル（せいぜい書籍数冊分程度）に対して、様々な条件を課して検索やそれに類する処理を行うというのが想定される主な使い方です。

大量のデータを対象にするのであれば、それに適したツールが他にたくさんあるので、そういうものを使ってください。ちなみに、ripgrep というコマンドが高速かつ高機能です。

また、greple は、すべてのデータを最初に読み込んでから処理するため、連続して生成されるデータを逐次処理していくような目的に使うことはできません。

## インストール

greple は Perl で記述されていて、cpanminus (cpanm) を使ってインストールします。cpanminus の使い方や、Perl の環境設定については、他の記事を参照してください。cpan や cpanplus など、他のインストーラーでも正しく使えば問題ないはずですが、保証はできません。

```
$ cpanm App::Greple
```

`-n` オプションをつけると、テストを省略して短時間でインストールすることができます。

## リポジトリ

ソースコードは [github](https://github.com/kaz-utashiro/greple) で管理しています。[cpan](https://metacpan.org/dist/App-Greple) にも、ほぼ最新版が上がっているので、どちらからインストールしても同じです。`cpanm` コマンドで、github の URL を指定してインストールすることもできます。

## 関連記事

https://qiita.com/kaz-utashiro/items/85add653a71a7e01c415

https://qiita.com/kaz-utashiro/items/8f4878300043ce7b73e7

https://qiita.com/kaz-utashiro/items/cde2b0df8b59b3627411

## SEE ALSO

https://qiita.com/advent-calendar/2021/greple

1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5 ←イマココ
2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
6. https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3
7. https://qiita.com/kaz-utashiro/items/0c8c944c17a72724b771
8. https://qiita.com/kaz-utashiro/items/8783c2fd0cc4315b9a3d
9. https://qiita.com/kaz-utashiro/items/84f5a6be6bf996076c64
10. https://qiita.com/kaz-utashiro/items/ebc7ea99f800cfc8c90c
11. https://qiita.com/kaz-utashiro/items/25a14e75380c39b5e0af
12. https://qiita.com/kaz-utashiro/items/ebbeb8a5538a15ff04fc
13. https://qiita.com/kaz-utashiro/items/b265deef9c9b1953a414
14. https://qiita.com/kaz-utashiro/items/2b20e0226cffde213ce0
15. https://qiita.com/kaz-utashiro/items/16b5142ef7a89aa35380
16. https://qiita.com/kaz-utashiro/items/d19fe5ee859f31ce172c
17. https://qiita.com/kaz-utashiro/items/09a5f5cf08ce314e2add
18. https://qiita.com/kaz-utashiro/items/6e4b1f51455e587ef743

- https://github.com/kaz-utashiro/greple.git
- https://metacpan.org/dist/App-Greple