OmniAICreator/Qiita-1.07M huggingface dataset:
ActiveHashを用いたプルダウンメニューでの検索機能の備忘録

オリジナルの写真投稿アプリを制作した際にActiveHashを用いたプルダウンメニューでの検索機能を実装したので備忘録に残します。
ransackを用いて実装しています。
ActiveHashの作成については書いていません。

### Gemの導入
Gemfileの最下部へ以下を記述してインストール
```
gem 'ransack'
```
```
bundle install
```

### ルーティングを設定
検索結果を一覧で表示したいので検索結果ページへのルーティングを記述する
collectionオプションでpostsコントローラー内のseachアクションに繋がるように設定
```:routes.rb
resources :posts do
    collection do
      get 'search'
    end
  end
```

### コントローラーにseachアクションを記述

```:posts_controller.rb
  def search
    @q = Post.ransack(params[:q])
    @items = @q.result.order('created_at DESC')
  end
```
ransackメソッドで検索オブジェクトを生成し変数に代入
params[:q]にはこの後に作成するフォームから送られてくるパラメーターが入る
resultメソッドで検索結果を取得する


### 検索フォームを作成
どのページからでも検索できるようにヘッターに記述
検索フォームを実装する際に使うsearch_form_forメソッドの引数には、コントローラーで定義した@qを渡す
```:_header.html.erb
 <%= search_form_for @q, url: search_posts_path do |f| %>
   <div class="search-field">
      <% f.label :brand_id_eq  %>
        <br>
       <%= f.collection_select(:brand_id_eq, Brand.all, :id, :name, {}) %>
       <%= f.submit '検索する', id:"submit-btn" %>
   </div>
 <% end %>
```
labelにはActiveHashを指定し、完全に一致する検索結果を表示したいので_eqオプションを追記
f.collection_selectにもActiveHashを指定する
第一引数がカラム名、第二引数が配列データ、第三引数が表示する際に参照するDBカラム名、第四引数が実際に表示するカラム名、第五引数は何も選択していない時に表示される内容だけどActiveHashの方で設定してあるので空にする

これで検索フォームの作成はできたが今のままだと何も選択しなくても検索ボタンが押せてしまうので選択してからでないとボタンが押せないようにする

### app/javascript下にsubmit.jsを作成
 下記の記述で選択してからでないとボタンが押せないように設定できる
```:submit.js
window.addEventListener('DOMContentLoaded', function(){
  $( '#submit-btn' ).prop( 'disabled', true );
  
  $('#q_brand_id_eq').on('change', function(){
      
      const selected = $('#q_brand_id_eq').val();
      if( selected !== '' ){
          $('#submit-btn').prop('disabled', false);
      } else {
          $('#submit-btn').prop('disabled', true);
      }
  })
  });
```

### 検索結果ページの作成
```:searh.html.erb
<div class="search-tittle">ブランド検索一覧</div>
<div class="index-main"> 
  <% @items.each do |post| %>
      <div class="index-post-wrapper">
        <div class="index-post-items">
          <div class="index-post-image">
            <% post.images.each do |images| %>
                <%= image_tag images, class: :post__img %>
                <% end %>
          </div>
          <ul class="index-post-list">
             <li class="index-post-list-first">投稿日：<%= post.created_at.strftime('%Y/%m/%d') %></li>
              <li class="index-post-list-first">ブランド：<%= post.brand.name %></li>
              <li class="index-post-list-first">投稿者： <%=  "@" + post.user.name %></li>
              <li class="index-post-list-first"> 選択頻度：<%= post.washing_frequency %></li>
              <li class="index-post-list-first">着用年数：<%= post.wearing_years %></li>
              <li class="index-post-list-first"><%= link_to '詳細を見る', post_path(post.id), class: "root-show-btn" %> </li>
          </ul>
        </div>
      </div>  
  <% end %>
  <% if @items.blank? then %>
    <div class="blank-tittle">選択したブランドの投稿はありません</div>
  <% end %>
</div>
```

以上が検索機能の実装が終わりました。
検索機能の実装自体は調べればすぐ出てくるしプルダウンメニューはすでに作成してあったので意外と簡単だったんですが選択しないとボタンが押せないようにするのが大変でした。
JavaScriptの仕組みをもっと理解しなければ…
LPC812MAXとS-5851Aで温度をシリアルに出力(小数点)


x mbed2リビジョン144
x リビジョンを変更できる人むけ


目的
精度の関係で意味は、ないけど小数部も受信する
わかりやすくて見やすいから小数点以下2ビットとする0,.25,.50,.75



- o_con527.jpg -



![o_con527.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f1707cc2-5b4a-8b37-669b-ab589af77163.jpeg)




![o_con738.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7ee41e19-6149-7608-0fc2-687636661190.jpeg)





```c++



// SER_test1_5851_812_1

#include "mbed.h"

//         TX    RX
Serial pc(P0_4, P0_0); //812

//       SDA    SCL
I2C i2c(P0_10, P0_11); //812

//メイン関数
int main()
{

    char data_read[8];  //バッファー

    //無限ループ
    while(1) {

        //初期化
        //set address 0
        i2c.write(0x90, "\000", 1);
        wait_ms(1); //addres 0

        //温度の読み込み
        // Read temperature register
        i2c.read(0x90 | 1, data_read,2);
        wait_ms(1);

        //温度の表示
        pc.printf("%2d", data_read[0] );
        char  *f4[] = {".0", ".25", ".5", ".75"};
        pc.printf( f4[data_read[1]>>6] );
        pc.printf( "\r\n" );

        //1秒待つ
        wait_ms(1000);

    }//while

}//main





```


![o_con833.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/bd67d110-87cf-6227-3ec4-65892627d36f.jpeg)


-20-
【Ruby on Rails】愛犬管理アプリpart3 ~体調管理編~【初心者向け】


# はじめに
この記事は、[こちら](https://qiita.com/tak8_al/items/08274dd9228363642555)の記事の続編です。
まだご覧になっていない方は是非ご覧ください。

# 実装内容
本記事では、簡単なCRUDアプリの作成と、検索機能の付与を行います。

手順は以下になります。
①体調に関するCRUD機能を持ったアプリケーションの作成
②体調に関するキーワードで検索できる機能の作成
③体調ペットの表示&体調を登録したユーザーの表示

![スクリーンショット 2022-09-12 午前10.15.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1973643/a899ca2f-c195-f022-427a-aa960405ee91.png)

ではさっそく実装していきましょう。

# ①体調に関するCRUD機能を持ったアプリケーションの作成
以下のコマンドを実行してください。
③、④の機能の実装のために、アソシエーションが必要なので、外部キーも設定しておきます。
```:terminal
$ rails g scaffold Health user:references pet:references title:string content:text   
```
完了したらrails db:migrateをしましょう。
これで、CRUD機能を持ったアプリケーションができました。

# ②体調に関するキーワードで検索できる機能の作成
* ルーティング定義
* 検索フォームの作成
* コントローラーへの追記
* モデル内に検索方法を記載

## ルーティング定義
routes.rbに以下を追記します。
```ruby:config/routes.rb
get 'search' => 'healths#search'
```
healthコントローラーのsearchアクションが実行されるよう定義しました。

## 検索フォームの作成
```erb:app/views/healths/index.html.erb
  <div class="search-form">
    #検索内容を、先ほど作成したルーティングに送信
    <%= form_with url: search_path, method: :get, local: true do |f| %>
       #検索内容を、keywordとしてアクションに送信
      <%= f.text_field :keyword, value: @keyword %>
      <%= f.submit "検索" %>
    <% end %>
  </div> 
```

## コントローラーへ追記
ヘルスコントローラーへサーチアクションを定義します。
```ruby:app/controllers/healths_controller.rb
  def search
    #検索モデルの定義
    @keyword = params[:keyword]
    #検索されたワードを表示するよう設定
    @healths = Health.search(params[:keyword])
    render "index"
  end
```

## モデル内に検索方法の定義
モデルに以下を追記します。
```ruby:app/models/health.rb
 def self.search(keyword)
    where(["title like? OR content like?", "%#{keyword}%", "%#{keyword}%"])
  end
```
検索をかけるキーワードを設定します。
上記のように設定することで、入力したワードに該当する"title"、"content"のデータを取得します。

# ③体調ペットの表示&体調を登録したユーザーの表示
二つのファイルに追記します。
* new.html.erb
* index.html.erb

## new.html.erb
```erb:app/views/healths/index.html.erb
#ここから追記
  <div class="field">
    <%= form.label :ペット名 %><br>
    <%= form.collection_select(:pet_id,@pets,:id,:name)%>
  </div>
   #今ログインしているユーザーの情報をuser_idのカラムに追加する。
  <%= form.hidden_field :user_id, :value => current_user.id %>
#ここまで追記
```

## index.html.erb
```erb:app/views/healths/index.html.erb
#追記
<td><%= health.pet.name %></td>
<td><%= health.user.name %></td>
```
既にアソシエーションの定義、pet_id、user_idのカラムの追加を行っているので、上記のコードを追記すれば、ペットの名前を取得できます。

# 終わりに
part1,part2で複雑な処理は済ましてしまっていたので、part3は簡単でしたね！
以上でオリジナルアプリケーションの全ての実装の解説が完了です。
まだまだ磨きをかけて、使いやすいアプリを目指します！
express.jsインストール後、expressコマンドが使えない。[-bash: express: command not found]

express.jsをインストール
```ruby:console
npm i express-generator -g
```
![スクリーンショット 2022-09-10 13.58.44のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223785/624f27bf-e9d6-92a9-38b4-80530d28674f.png)
インストールは出来たけど、バージョン確認のexpressコマンドが効かない
```ruby:console
express --version
```
に対して
```ruby:console
-bash: express: command not found
```
このコマンドだとバージョン確認ができる。
```ruby:console
npm view express version
```
```ruby:console
4.18.1
```
次にアプリケーション雛形を作成したい。
```ruby:console
express --no-view server
```
に対して
```ruby:console
-bash: express: command not found
```
![スクリーンショット 2022-09-10 14.33.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223785/1f96bb7a-6fb5-fff2-d300-f634275fd490.png)

？？？？

答えはパスが通っていなかった。
npmのpathを確認する。
```ruby:console
npm bin -g 
```
私の場合
```ruby:console
/Users/ユーザー名/.npm-global/bin
```
これを.bash_profile に設定する。
```ruby:console
vim ~/.bash_profile
```
```ruby:vim ~/.bash_profile
#expressの環境変数
export PATH=/Users/ユーザー名/.npm-global/bin:$PATH
```
設定の読み込み。
```ruby:console
source ~/.bash_profile
```
再度、expressコマンドを入力
```ruby:console
express --version
```
```ruby:console
4.16.1
```
![スクリーンショット 2022-09-10 14.24.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223785/eae33abf-8cf2-984b-3f38-845bbfb3bbcb.png)
できた:sob:

中途半端に「npm view express versionで確認が取れた」と思い込んでいたため、パスが通っていないとは思ってもいなかったです:scream:
discordのwebhookを使用してgoから通知を送ってみた

無料版slackだとデータが消えていってしまうということでslackに飛ばしていた通知をdiscordに飛ばせないかと思い実装をしてみました！

参考文献：　https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks

# 1. webhook_url取得
まずはここからですね。

1. 通知したいチャンネルの設定を開きます
![スクリーンショット 2022-09-10 13.27.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645779/ec57608c-7b4d-c290-4c9c-1de2630dbce8.png)

2. 連帯サービス >　ウェブフックURLコピーをクリックして取得します
![スクリーンショット 2022-09-10 13.29.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645779/bab41855-c6b6-6ed0-0812-df528f656d27.png)

ここでチャンネルの変更とか可能です。

# 2. 実装

```main.go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type Discord struct {
	Username  string `json:"username"`
	AvatarUrl string `json:"avatar_url"`
	Content   string `json:"content"`
}

func main() {
	var discord Discord
	discord.Username = "Mr. Hogehoge"
	discord.AvatarUrl = "https://github.com/qiita.png"
	discord.Content = "Hello World!"

	// encode json
	discord_json, _ := json.Marshal(discord)
	fmt.Println(string(discord_json))

	// discord webhook_url
	webhook_url := "取得したURL"
	res, _ := http.Post(
		webhook_url,
		"application/json",
		bytes.NewBuffer(discord_json),
	)
	defer res.Body.Close()
}

```

はい！これで

``
go run main.go
``
を実行すると以下のように通知ができます。
![スクリーンショット 2022-09-10 14.04.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645779/f812dcdd-9abf-8322-1cae-ec1daf3801cd.png)

# 3. 解説編

最終的にjsonでdiscrodに対しPOSTリクエストしたいので

```go
res, _ := http.Post(
    webhook_url,
    "application/json",
    bytes.NewBuffer(discord_json),
)
```

これに当てはめる必要があります。

http.Post関数は以下のように定義されているので
```go
func http.Post(url string, contentType string, body io.Reader) (resp *http.Response, err error)
```
各々の変数には
* 変数1 > リクエスト先URL（今回は取得したURL）
* 変数２ > contentType(今回はjson形式なので"application/json")
* 変数３ > リクエストボディ（json）

を入れる必要があります。

変数1, 2は単純ですが３に関しては工夫が必要で、今回はstructを用意しそれをjsonに変換して代入する手段を取りました。以下の部分ですね。

```go
// encode json
discord_json, _ := json.Marshal(discord)
fmt.Println(string(discord_json))
```

とこのような感じで実装することができます。

# 4. まとめ
slackの代わりにdiscordでいけそうなので個人的にはdiscordを使うことが多くなりそうです！
他にもメンションの設定とか色々できるので公式ドキュメント見てみると楽しいと思いますよ！

以上です！お疲れ様でした！！

今回実装したソースコードは以下です。
https://github.com/taiki-nd/go_discord
ITパスポートを取ってよかったこと

# ITパスポート試験とは？
* IT系の資格の中では難易度低め
* ITに関する基礎知識が問われる
# 合格してよかったこと
* 資格手当がもらえる（これは会社によりますよね）
* ITに関する基礎知識が身に付く
* 勉強中、意外と楽しい
    * PCの仕組みって？CPUって何してるの？辺りは特に楽しかった
* 仕事中にフワッと理解してたことが腑に落ちて理解できた
* 仕事中にサラっと出てきたワードが理解できる
    * 例：公開鍵と共通鍵とか
* セキュリティはめちゃめちゃ大事ってことが理解できる
* 美容業界からIT業界に来た身だが、「基本的なことは理解してます」ってわかりやすく示せる
# 勉強する上で気をつけたこと
## 問題数が多いテクノロジ系に多く時間を使う。
テクノロジ系（IT技術）：45問程度
ストラテジ系（経営全般）：35問程度
マネジメント系（IT管理）：20問程度
# とりあえず受験日決めて申し込んでから勉強をする 
受かっても落ちても、このやり方のが頭に入ってる気がする。
# さいごに
特に他業種からITの分野にやってきた人にはオススメかなと思います。
仕事中の会話に意味不明なフレーズが登場した時にスッと理解できると結構楽です。（自分も相手も）
【Figma】色んなプラグイン入れてみた。

# この記事について
便利そうなダウンロード無料プラグインをとにかく入れてみて、レビューを記事にしてみました！
使い方がわかりずらそうなものだけ使い方の説明も入れてます。
個人的に⭐️５だったものから順に紹介します。順次更新します🙋‍♀️
⚠️Figmaの使い方については説明しませんので、注意してください。

また、この記事ではあくまで私個人の感想になってしまうので、皆さんの感想もコメントで共有頂ける嬉しいです♪


# [Deca Kit for Figma](https://deca.craftwork.design/)⭐️⭐️⭐️
![スクリーンショット 2022-09-10 12.40.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529394/1ea7be25-6ac8-5588-23f6-39348a8836bb.png)

<dl>
  <dt>内容</dt>
  <dd>デザインのキットを購入できる（一部のみ無料）</dd>
  <dt>所感</dt>
  <dd>初心者にはすごくいい</dd>
  <dt>感想</dt>
  <dd>ある程度Figmaを使える人はそこまで必要ないかなという印象。有料のものはデザイン性が高いので需要はありそう。　個人的には、デザインの参考に使えそうだな、と思う。</dd>
  <dt>使い方</dt>
  <dd>"Explore more UI kits" ボタンからページに遷移</dd>
  <dd>❶　遷移先のページにて　"Free"　と検索すると無料のテンプレートのみが表示される</dd>
  <dd>❷　好きなサイトのデザインを選んで "Get for free" ボタンより手順に従ってダウンロードする</dd>
  <dd>❸　Figmaを開いて右上の　"ファイルをインポート"　より、ダウンロードしたファイルを選択</dd>
  <dd>❹　Finderが開かれるので先ほどダウンロードしたファイルを選択して "開く" でデザインがアップロードされる</dd>
  <dt>皆さんの使ってみた感想もぜひコメントで教えてください！</dt>
</dl>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529394/e1531828-05d7-cc31-f377-3d06a0314c3a.png" width=50%　title="1"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529394/ac132099-15ca-d435-1785-06b7da2dbbe3.png" width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529394/1b2575bf-d1fc-cc10-6ad8-98d9254f7f70.png" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529394/9ba0a26c-96b3-e879-cf32-791f73f50231.png" width=50%>


# [Better Font Picker](https://www.figma.com/community/plugin/739922281164562258/Better-Font-Picker)⭐️⭐️
![スクリーンショット 2022-12-03 14.37.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529394/9e9e51fb-1a5b-d428-0fcc-6a85c715024e.png)
<dl>
  <dt>内容</dt>
  <dd>フォント専用のサイドバーが出てくる</dd>
  <dt>所感</dt>
  <dd>使えるけど機能が不十分</dd>
  <dt>感想</dt>
  <dd>Figmaでフォント選択を行う時にフォント名が全て同一フォントのため、どのフォントがどれなのかわかりずらい部分があるのをこのサイドバーは補ってくれる。　だけど、自分の書いたテキストに対してのフォント適用は選択しないと見れないので、サイドバーのフォント名をマウスオーバーでフォント適用される機能が欲しいと心から思う。また、日本語非対応なのも機能追加求むって感じ。</dd>
  <dt>皆さんの使ってみた感想もぜひコメントで教えてください！</dt>
</dl>


<!--
# おまけ
ここではダウンロード自体は無料だけど、お金を払わないと使い続けられないプラグインをまとめています。どれもお試し期間があるので、継続するかは試してから決めるのもありかな？と思います。

## [Design System Organizer](https://www.figma.com/community/plugin/802579985985331070/Design-System-Organizer)⭐️⭐️
![スクリーンショット 2022-12-03 20.39.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529394/8067e333-bf09-3b2a-e418-1bfa838b464b.png)
<dl>
  <dt>内容</dt>
  <dd>デザインのコンポーネント化して管理できる</dd>
  <dt>所感</dt>
  <dd></dd>
  <dt>感想</dt>
  <dd></dd>
  <dt>備考</dt>
  <dd>15日間は無料。それ以降は一回限りの購入で$２４~使用できる。料金詳細は　[こちら](https://floweare.gumroad.com/l/dsoplugin)</dd>
</dl>
-->
メソッド の 引数

# 目的
メソッドにおける引数の使い方を理解する

# ポイント
- 引数を使うことで、インスタンスごとにメソッドを作る必要が無くなる

# 書き方の例
```ruby
require "pry"
def buy_fruits(fruit)

  if fruit == "apple"
    puts "りんごを渡す"
  elsif fruit == "banana"
    puts "バナナを渡す"
  elsif fruit == "lemmon"
    puts "レモンを渡す"
  end

  fruit

end

binding.pry
fruit = "apple"
buy_fruits(fruit)

```
~実際の表示~
 32:   fruit
    33: 
    34: end
    35: 
    36: binding.pry
 => 37: fruit = "apple"
    38: buy_fruits(fruit)

[1] pry(main)> continue
りんごを渡す
# 注意するポイント
- 引数の順序は基本的に固定される
- キーワード引数を使えば、引数の順序を変えても問題ない。

# 具体的な例
```ruby
def buy_items(item:, money:)
  puts "#{money}円入れる"

  if item == "tea"
    puts "お茶を渡す"
  elsif item == "water"
    puts "水を渡す"
  else
    puts "#{money}円返す"
  end
end

buy_items(money: 200, item: "tea")

```
~実際の表示~
200円入れる
お茶を渡す
インタープリタ言語とコンパイラ言語

# インタープリタとコンパイルとは？
どちらもプログラムをPCが理解できる言語に変換する作業のことだけど、その方法が違う。
※「PCが理解できる言語」は0と1だけを使って表す2進数のこと。

# インタープリタ言語とは？
プログラムを1行ずつPCが理解できる言語に翻訳しながら動かす言語。
同時通訳家って表現がわかりやすい。
## メリット
実行結果が細かく確認できる。
## デメリット
コンパイラ言語より遅いらしい。
## インタープリタ言語の例
Python, PHP, javascriptなど

# コンパイラ言語
全部一気に翻訳してから動かす言語
翻訳家って表現がわかりやすい
## メリット
・実行速度が速いらしい(使ったことないから体感したことはない。。)
## デメリット
・プログラムが全て完成するまで実行結果が確認できない
・つまりデバッグがやりにくい
## コンパイラ型言語の例
C言語, Java, Goなど
C# UserControl(子)からForm(親)へのイベント通知

UserControl(子)でイベントが発火して、Form(親)で受け取りたい場合の自分用備忘録です。


# UserControlとFormのデザイン
![実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546646/bc80e5b5-d596-8d38-500a-a3ea04b55b43.png)
※ 黄色い範囲と内側のボタンがユーザーコントロール

# UserControlとFormのコード
## UserControl側（イベント発生側）
```C#:
    public partial class MyUserControl : UserControl
    {
        // -------------------------------------------------------------
        // デリゲートイベントの定義
        // -------------------------------------------------------------
        // 親へイベントをデリゲートするためのイベントハンドラを定義
        public delegate void OnFruitSelectedEventHandler(OnFruitSelectedEventArgs e);
        public event OnFruitSelectedEventHandler OnFruitSelected;
 
       // デリゲートの引数を定義
        public class OnFruitSelectedEventArgs : EventArgs
        {
            public string strFruit;
        }

        // -------------------------------------------------------------
        // 初期化とロード
        // -------------------------------------------------------------
        public MyUserControl()
        {
            InitializeComponent();
        }

        // -------------------------------------------------------------
        // イベントの発火
        // -------------------------------------------------------------
        private void buttonApple_Click(object sender, EventArgs e)
        {
            // イベントの引数を設定
            var arg = new OnFruitSelectedEventArgs { 
                strFruit = "りんご"
            };
            // イベントの発火
            OnFruitSelected(arg);
        }

        private void buttonWatermelon_Click(object sender, EventArgs e)
        {
            // イベントの引数を設定
            var arg = new OnFruitSelectedEventArgs { 
                strFruit = "スイカ" 
            };
            // イベントの発火
            OnFruitSelected(arg);
        }
    }
```

## Form側（イベント受信側）
```C#:
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // ユーザーコントロールで発火するイベントハンドラを追加
            myUserControl.OnFruitSelected += OnFruit_Selected;

        }

        // イベント発火時の処理
        private void OnFruit_Selected(OnFruitSelectedEventArgs e)
        {
            myLabel.Text = e.strFruit;
        }
    }
```
Macでフルスクリーンにせずにアプリのウィンドウをモニターいっぱいに最大化

# やり方

```Option + 左上の最大化の緑ボタン```
緑ボタンを押すだけだとフルスクリーンになってしまう。
でも **Option押しながら** だとフルスクリーンにならずに、ウィンドウをモニターいっぱいに最大化できる。 

ウィンドウをドラッグでモニター左上まで持っていって、右下をドラッグしながら広げる…
なんてことはしなくてOK。

# タイル表示

Option押しながら緑ボタンの上にカーソルを持っていくと、下記メニューが出てくる。
作業によってはタイル表示した方が便利なこともあるので、覚えておくとお得。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a57fe38c-be68-5769-16a2-f98a04323690.png)

# 参考サイトさん

https://support.apple.com/ja-jp/guide/mac-help/mchlp2469/mac

# バージョン

macOS Monterey バージョン12.5.1
【mac】ターミナルからpycharm起動

## 環境変数追加
今回は既にPATHに登録してある`/usr/bin:`にpycharmのpathへのリンクを貼ります。

リンク（Symlink)追加方法
`ln -s <target-path> <link-path>`

```terminal
$ ln -s /Applications/PyCharm\ CE.app /usr/local/bin/.                            
```

## ターミナルからpycharm起動
```
$ charm .
```
PowerShellのプロンプトの表示をカスタマイズする(短くしたり)

## TL;DR

フォルダー階層が深すぎるとき、PowerShellのプロンプトが長くなり過ぎて見にくい。この場合だけある程度短いパスで表示するように変更してみるよ。
変更の維持・反映にはユーザーのProfileを使用するよ。

似たような文脈のネタで[PyCharmでteminalを(venv)pwshにする](https://qiita.com/bounoki/items/346d164a2016b55b0a7d)というのも書いているので、今はもう起こらないかもしれないけど、同じことでハマってる方はご参考まで。

## 何はともあれプロファイルスクリプトの場所

利用しているユーザーのプロファイルを設定するスクリプトの場所を調べる。bashでいうところの`~/.bash_profile`(いや、`.bashrc`か？まあいいか)。

`$profile`を参照して `Microsoft.PowerShell_profile.ps1` があるパスを見つける[^1]。

```shell
PS> Write-Host $profile
# U:\path\to\Microsoft.PowerShell_profile.ps1
```

## プロファイルを編集する

そしたら適当なエディタで開いて、中身を編集する。

```shell
PS> code $profile   # VSCodeで開く
```

ここに`prompt`という関数を作ると、それが反映される。
今回は、

- 文字数が42を超えたら間を"…"で省略する
- でも、今いるフォルダ名は全文で出す
- そもそも今いるフォルダ名が長すぎる場合は"…\超長いフォルダ名"みたいに出す

をしてみる。ついでに、サンプルにあったやつで、管理者権限なら管理者権限とわかるようにするのをやってみる。

ちゃんとテストしてないのでおかしなところあったらご指摘くださいまし。

```powershell
function prompt {
    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = [Security.Principal.WindowsPrincipal] $identity
    $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator
    $ctx_txt = ''
    if (Test-Path variable:/PSDebugContext) { $ctx_txt = '(DBG)' }
    elseif ($principal.IsInRole($adminRole)) { $ctx_txt = '(ADM)' }
    else { $ctx_txt = '' }

    $location_path = ( Get-Location ).path
    $max_path_len = 42
    $location_path_to_show = ""

    if ($location_path.Length -gt $max_path_len) {
        $leaf = ( Split-Path $location_path -Leaf )
        
        if ( $leaf.Length -gt $max_path_len ) {
            $location_path_to_show = "…\" + $leaf
        }
        else {
            [int]$b = $max_path_len - $leaf.Length
            $location_path_to_show = $location_path.Substring(0, $b) + "…\" + $leaf
        }
    }
    else {
        $location_path_to_show = (Get-Location).Path
    }

    'PS' + $ctx_txt + ' ' + $location_path_to_show +
    $(if ($NestedPromptLevel -ge 1) { '>>' }) + '> '
}

```

## 結果

できた。

```powershell
PS Microsoft.PowerShell.Core\Fi…\@2022_work>
```

## Links

- **about_Prompts**
    - プロンプトの変更について。本記事のサンプルもここを元ネタにした。
    - <https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_prompts>
- **about_Profiles**
    - profileの使い方について。`about_Profiles`には「Current user, Current Hostは`$Home\Documents\PowerShell\Microsoft.PowerShell_profile.ps1`」だと書いてあるけど、ホームフォルダーを変更している人には期待した挙動をしてくれない可能性がある。本記事に記載しているように実際に実行しているPowerShellが参照しているプロファイルを参照したほうが確実かと思う。
    - <https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_profiles>

[^1]: `$profile`はVSCodeで参照すると`Microsoft.VSCode_profile.ps1` (VSCodeのprofile)を返すようなので、VSCodeのPowerShell Extentionでプロファイルを探す場合には一回`powershell`(またはps coreを使ってるなら`pwsh`)を叩いてから`Write-Host $profile`叩くとよい。
Node + Denoで使えるテンプレートエンジンEta（イータ）


## はじめに
良さそうなnode.js向けレンダリングエンジンを見つけたので紹介させてください。
[Eta](https://eta.js.org)と言います。node.jsでの利用のほか、CDNでの利用、Denoでの利用が可能のようです。
jsでの軽量単体アプリケーションフレームワーク([Neutralino](https://neutralino.js.org/))での使用も可能でした
いづれDenoに乗り換える際サーバサイドレンダリングのロジック部分をそのまま使おうという魂胆で使ってみました。
軽量で高速に動作するようです。Fastifyでメモリ上にバッファすればさらに最強と見てます。
[ect](https://github.com/baryshev/ect)最強と思ってましたがこれもいいかもです。ちなみにectとは無関係のようです。

読み方はイータになります。
アルファ・ベータ・デルタ・シータ・イータのイータです
Etaユーザが増えた際イーティーエー等誤った読み方が定着することを全力で阻止するための投稿になります。
以上。

## おまけ
今回小さなアプリケーションを作って試した際の知見を残しておきたいと思います。
node:v16.13.0
eta:v1.12.3

### レンダリング実行
```js:logic.js
let template = "<div><%= it.title %></div>";
let htmlString = Eta.render(template ,{ title: 'タイトル' ,type: 'integer' ,name: '名前' });
```

### 値の表示
```rhtml:template.eta
<%= it.name %>
```

### jsの実行
```rhtml:template.eta
<% console.log("ログ"); %>
```

### 条件分岐
```rhtml:template.eta
<% if (it.type == 'integer') { %>
    <%= it.name %>?:number;
<% } %>
<% else if (it.type == 'object') { %>
    <%= it.name %>?:Object;
<% } %>
<% else { %>
    <%= it.name %>?:<%= it.type %>;
<% } %>
```

### 反復
`<% %>`内にjs書けるってことです

#### array
```rhtml:template.eta
<% users.forEach(function(user){ %>
  <%= user.first %> <%= user.last %>
<% }) %>
```
#### object
```rhtml:template.eta
<% Object.keys(someObject).forEach(function(prop) { %>
  <%= someObject[prop] %>
<% }) %>
```

### インクルード
```rhtml:template.eta
<%~ include(name, options) %>
<%~ includeFile(path, options) %>
```

## ホントは読み方はどうでもよくむしろここからが本題
他のテンプレートエンジン使った人なら予想がつくかもしれませんが、公式サイトやstackoverflowにもなく、ちょと悩んだので備忘録です

### テンプレート内で関数実行
今回[Sugar](https://sugarjs.com/)と言うユーティリティ系のライブラリを使ってキャメルケースに変換します

```js:logic.js
let entitySrc = Eta.render(entityFile ,{ name:"class_name"  ,camelize :Sugar.String.camelize });
```

```rhtml:template.eta
<%= it.camelize(it.name) %>;
```
### テンプレートを再帰的にレンダリング
```js:logic.js
let self = "<% names.forEach(function(name){ %> <%= name.first %> <%= name.last %> <%~ Eta.render( it.self, { names: it.names.arr ,self: it.self  }) %> <% }) %>";
let htmlString = Eta.render(self ,{ 'names': array ,'self': self });
```

※ちょっと良くない例になってしまったのですがnamesが内部にさらにarrayを持っている想定です。雰囲気で理解
it.selfにテンプレート文字列を渡してtenplate内でもう一回render関数を呼んでます
以下の部分でリカーシブ
```rhtml:js内の再帰呼び出し部分
<%~ Eta.render( it.self, { arr: it.names.arr ,self: it.self  }) %>
```
AWS DynamoDBのローカルセカンダリインデックス(LSI)とグローバルセカンダリインデックス（GSI)をまとめる

AWS DVA試験勉強で、DynamoDBのローカルセカンダリインデックス(LSI)とグローバルセカンダリインデックス（GSI)が分からなかったので、理解をするためにまとめる。


## そもそもDynamoDBとは
NoSQLでサーバーレス。即時一貫性と操作の原子性（トランザクション処理が完了か未処理かどっちかの状態）と検索条件の自由を捨て、可用性と拡張性に特化したデータベース。

"table" "item（項目、行）" "attribute（属性、列）"の3つの概念にプラスして、"key"（＝ハッシュキー） "index"という概念がある。

"key"は"item"を検索するために必要な値で、それ故にユニークである必要がある。（逆に言うと、Dynamoではkeyのみユニークにできる）
なので{"key":"1","food":"トマト"}と{"key":"1","game":"ドラクエ"}は同じtableに保存できない。
また、"key"にはパーティションキーとソートキーの種類がある。この2つのキーを使ったものが複合キーテーブルと呼ばれる。
ちなみに、"key"で検索する時の動作としては、全体をスキャンして"key"から"item"を探す処理になる。

"index"とは、検索用のデータを"table"とは別に保存して、検索を高速化するもの。
ユニークである必要はない。

## ローカルセカンダリインデックス(LSI)
**前提として、複合キーテーブルにしかLSIは定義できない。**
パーティションキーとソートキーでの検索結果からさらに検索できる。

```
例）　tableの中で、お料理レシピ9月版から2022-09-01に投稿された肉に関連するレシピを探す
パーティションキー　["Id":"お料理レシピ9月版"]
ソートキー["Time":"2022-09-01"]
LSI["genre":"meat"]
```
LSIはパーティションキーを指定できず、同じパーティション内での検索になるので「ローカル」と言う名前がついている。
また、LSIは後から追加できないので、table作成時に設定しなければいけいない。

## グローバルセカンダリインデックス（GSI)
**GSIはハッシュテーブルでも複合テーブルでも使える。**
```
例）　tableの中で、お料理レシピ9月版から2022-09-01に、useridに12を含んでいる男性ユーザーから投稿されたレシピを探す
パーティションキー　["Id":"お料理レシピ9月版"]
ソートキー["Time":"2022-09-01"]
GSI["userid":"12"] ["usergender":"men"]
```
また、GSIは任意のタイミングで追加することができる。
ignored_columns が意図せず上書きされるのを防ぐ


## [ignored_columns](https://edgeapi.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-ignored_columns) が意図せず上書きされる可能性のあるコード
一つのモデルで既に ignored_columns をセットしていた場合に、誤って新規に ignored_columns をセットしてしまうと本来使われたくないカラムが使われてしまう不具合が引き起こされる恐れがある。

```rb
# あるモデルの10行目に ignored_columns がセットされている
self.ignored_columns = %w(foo bar)

...

# 10行目に気づかず別の行に新規で書いてしまうと10行目の ignored_columns は上書きされ、
# foo, bar のカラムが意図せず利用可能になってしまう
self.ignored_columns = %w(baz)
```

## これを防ぐためには
以下のように変更するだけ

```rb
# before
self.ignored_columns = %w(foo bar)

# after
self.ignored_columns += %w(foo bar)
```

### 2022/10/14 追記
Rubocop Rails 2.17.0にバージョンアップ以降は [`Rails/IgnoredColumnsAssignment`](https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsignoredcolumnsassignment) を有効化すればAuto Correct (Unsafe) 可能
https://github.com/rubocop/rubocop-rails/releases/tag/v2.17.0

```yml
Rails/IgnoredColumnsAssignment:
  Enabled: true

# or

AllCops:
  NewCops: enable
```

## 背景について

Rails本体のmainブランチに下記ドキュメント修正が入ったのを受けて。
https://github.com/rails/rails/pull/45909

また、同様のドキュメント変更がRails Style Guideに既に入っており、
https://github.com/rubocop/rails-style-guide/pull/301

Rubocop Railsにもこれを推奨するCopが追加されようしている(記事執筆時点)のを観測
https://github.com/rubocop/rubocop-rails/pull/514

### 2022/10/14 追記
上記#514のマージが待ち切れず私の方で巻き取って対応の続きを進めることになり、
https://github.com/rubocop/rubocop-rails/pull/514#issuecomment-1243124817

rebaseのために別でオープンしたPullRequestが無事マージされた
https://github.com/rubocop/rubocop-rails/pull/771

---
Changelogにはco-authorという形で載せていただくことができました :tada: 
また、そのあたり配慮してくださった@koicさんに感謝です :pray: 

![Screen Shot 2022-10-24 at 9.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323366/0e07ac1c-8b22-3e6c-d815-dc35e70e175a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323366/a26bee45-0e71-495e-ba5b-280be6a2155d.png)

    
# 参考リンク

https://edgeapi.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-ignored_columns
docker起動時にエラー（docker: Error response from daemon: driver failed programming external connectivity on endpoint）

docker起動時にエラー

```sh
$ docker run -d --name ${CONTAINER_NAME} -p 6080:80 --shm-size=512m seigott/tetris_docker
docker: Error response from daemon: driver failed programming external connectivity on endpoint tetris_docker_gameserver
(9ab4c7e586ace4cc20ad57afdc56e19bb961f976a8803b3fd575e64c8f6ff254): Bind for 0.0.0.0:6080 failed: port is already allocated.
```

docker run 時に既存のコンテナとポート番号が重なったためエラー
bind先のポートを更新する事で解決（例えば 6080 --> 8080 にすることで解決）

```
docker run -d --name ${CONTAINER_NAME} -p 8080:80 --shm-size=512m seigott/tetris_docker
```

# 参考

https://qiita.com/ponsuke0531/items/f3490f571b5eee16ea87

https://qiita.com/hirokihello/items/69df88ba55125c2aed39
[jQueryUI sortable]id以外でソート順を取得したい

jQuery sortable を使うと、ブラウザ上での並び替えが直感的におこなうことができます。
以下の例で見てみましょう。

```HTML:HTML
<div id="sortable">
    <div id="1">りんご</div>
    <div id="2">バナナ</div>
    <div id="3">みかん</div>
</div>
```

並べ替え操作をおこなったときに発生するイベントの中で、ソート順を取得しDBを更新するときは以下のようなコードを記述します。

```Javascipt:jQuery
$('#sortable').sortable({
    update: function( event, ui ) {
        var sortIdArray = $('#sortable').sortable("toArray");
        $.ajax({
            // DBのソート順を更新する処理
        });
    }
});
```
sortable(“toArray”)によって、並び順で各要素に設定されているidが格納された配列になりますので、それをサーバーにポスト、処理するイメージです。

ただ、個人的には何か処理をするためのDOM要素の属性として、id（およびclass） は使いたくない派です。なのでたいてい下記のようにdata属性で値を設定するようなコーディングをしています。
```HTML:HTML
<div id="sortable">
    <div data-id="1">りんご</div>
    <div data-id="2">バナナ</div>
    <div data-id="3">みかん</div>
</div>
```

この場合のsortableの処理として、idではなくdata-idの値を取得するにはどうしたら良いでしょうか。

以下のように記述します。

```Javascipt:jQuery
$('#sortable').sortable({
    update: function( event, ui ) {
        var sortIdArray = $('#sortable').sortable("toArray", {attribute: 'data-id'});
        $.ajax({
            // DBのソート順を更新する処理
        });
    }
});
```

これで、data-id属性値が取得できるようになります。
Amazon Rekognition とは

## 勉強前イメージ

認識？

## 調査

### Amazon Rekognition とは

機械学習の専門知識が不要で画像認識やビデオの分析機能を使えるサービスになります。
物体を特定したりシーンの認識、顔やテキストの検出などの行うことができます。

機能としては以下の様なことができます。

- 物体の特定

画像内に写っている物体を特定します。
車や家、人などを検出します。

- シーンの特定

どこが写っているのか、屋内なのか特徴的などこの都市なのか判定します。

- カスタムラベル

カスタムラベルはユーザが画像データを準備してRekognitionに学習させることで
特定の商品などAWSで準備されていないものを認識させることができます。

逆に物体やシーンはAWSがすでに準備している学習データを使用します。

- 顔の検出

画像の中の人を検出します。
性別や大体の年齢などの情報を取得することができます。

- テキストの検出

画像内に含まれているテキストを検出することができます。
曲がってたりしても読み取りが可能です。

### Amazon Rekognition の料金

費用に関しては大きく以下で分かれます。

- Amazon Rekognition Image

画像についての料金です。
画像については1枚の分析に費用がかかるのと、
顔の検索を行う際は顔のメタデータというものを保存する必要があり、それに関するストレージ費用がかかってきます。

- Amazon Rekognition Video

ビデオについての料金です。
ビデオについての分析1分ごとに費用がかかるのと
画像と同様顔の検索を行う際は顔のメタデータというものを保存する必要があり、それに関するストレージ費用がかかってきます。

- Amazon Rekognition カスタムラベル

上記で記載した、独自の画像を読み取るカスタムラベルです。
カスタムラベルにはトレーニングが必要なので
トレーニングと処理について費用がかかります。

### Amazon Rekognition のユースケース

- 異常検知

正常系と異常系を準備しラベルを学習させておけば検査モデルを構築することができます。
飲料パッケージの亀裂や作物の状態を見分けることができます。

- ユーザ認証

顔認識でのユーザ認証ができるようになれば
顔とユーザIDを紐づけて+αで認証を行うことが可能になります。

## 勉強後イメージ

画像とかビデオでどこで取ってるとか誰が写ってるとか分析できるのね

## 参考

- [AWS Rekognitionとは？Rekognitionの機能や手順を紹介！](https://www.fenet.jp/aws/column/aws-beginner/796/)
- [ディープラーニングを利用した画像認識・分析を実装できるAmazon Rekognitionを解説](https://business.ntt-east.co.jp/content/cloudsolution/column-157.html)
yq で JSON ⇔ YAML の相互変換

# 概要
`yq` コマンドを用いて JSON ⇔ YAML の相互変換を行う。

# Install
最初に Mac 環境で `yq`をインストールする。

```
% brew install yq
```

## 環境
環境としては、カレントディレクトリに 以下の `commands.json`が存在している。
```
% cat commands.json
{
  "commands": [
    {"name": "ls", "desc": "list files"},
    {"name": "echo", "desc": "echo values"}
  ]
}
```

## 変換：json ⇒ yaml
最初に json ⇒ yaml の変換を行う。出力は標準出力に向けられている。
（`-P` でPretty Print 指定にすると `yaml` 形式になる）
```
% yq -P commands.json
commands:
  - name: ls
    desc: list files
  - name: echo
    desc: echo values
```

リダイレクトすれば ファイル出力が可能（以降のコマンドも同様）
```
% yq -P commands.json > commands.yml
```

> Ubuntu環境では以下のように実施
> ```bash
> $ cat commands.json | yq -y
> commands:
>   - name: ls
>     desc: list files
>   - name: echo
>     desc: echo values
> 
> ```

## 変換：yaml ⇒ json
次に yaml ⇒ json の変換をする。標準出力で確認するがリダイレクトも可能。

```
% yq -o json commands.yml
{
  "commands": [
    {
      "name": "ls",
      "desc": "list files"
    },
    {
      "name": "echo",
      "desc": "echo values"
    }
  ]
}
```

> Ubuntu環境では以下のように実施
> ```
> $ cat commands.yml | yq
> {
>   "commands": [
>     {
>       "name": "ls",
>       "desc": "list files"
>     },
>     {
>       "name": "echo",
>       "desc": "echo values"
>     }
>   ]
> }


## 変換：その他
蛇足だが xml や properties にも変換可能なようだ。使うかは別として。

```
% yq -o xml commands.json
<commands>
  <name>ls</name>
  <desc>list files</desc>
</commands>
<commands>
  <name>echo</name>
  <desc>echo values</desc>
</commands>
```

```
% yq -o props commands.json
commands.0.name = ls
commands.0.desc = list files
commands.1.name = echo
commands.1.desc = echo values
```
Visual Studioのビルド前・後イベントで使用できるマクロ

<br>
・マクロの大文字と小文字は区別されない。

|マクロ	|[説明]|
|---|---|
$(ConfigurationName)|	現在のプロジェクト構成の名前 ("Debug" など)。
$(OutDir)|	プロジェクト ディレクトリに対して相対的な、出力ファイル ディレクトリへのパス。 これは、Output Directory プロパティの値に解決されます。 最後に円記号 (\) が含まれます。
$(DevEnvDir)|	Visual Studio のインストール ディレクトリ (ドライブとパスで定義)。最後に円記号 (\) が含まれます。
$(PlatformName)|	現在対象となっているプラットフォームの名前。 たとえば、"AnyCPU" です。
$(ProjectDir)|	プロジェクトのディレクトリ (ドライブとパスで定義)。最後に円記号 (\) が含まれます。
$(ProjectPath)|	プロジェクトの絶対パス名 (ドライブ、パス、基本名、およびファイル拡張子で定義)。
$(ProjectName)|	プロジェクトの基本名です。
$(ProjectFileName)|	プロジェクトのファイル名 (基本名とファイル拡張子で定義)。
$(ProjectExt)|	プロジェクトのファイル拡張子。 ファイル拡張子の前にピリオド '.' が付きます。
$(SolutionDir)|	ソリューションのディレクトリ (ドライブとパスで定義)。最後に円記号 (\) が含まれます。
$(SolutionPath)|	ソリューションの絶対パス名 (ドライブ、パス、基本名、およびファイル拡張子で定義)。
$(SolutionName)|	ソリューションの基本名です。
$(SolutionFileName)|	ソリューションのファイル名 (基本名とファイル拡張子で定義)。
$(SolutionExt)|	ソリューションのファイル拡張子です。 ファイル拡張子の前にピリオド '.' が付きます。
$(TargetDir)|	ビルドのプライマリ出力ファイルのディレクトリ (ドライブとパスで定義)。 最後に円記号 (\) が含まれます。
$(TargetPath)|	ビルドのプライマリ出力ファイルの絶対パス名 (ドライブ、パス、基本名、およびファイル拡張子で定義)。
$(TargetName)|	ビルドのプライマリ出力ファイルの基本名です。
$(TargetFileName)|	ビルドのプライマリ出力ファイルのファイル名 (基本名とファイル拡張子で定義)。
$(TargetExt)|	ビルドのプライマリ出力ファイルのファイル拡張子。 ファイル拡張子の前にピリオド '.' が付きます。
既存のソースをオブジェクト対応にした苦労ばなし

# 概要
すでにあるソースコードをオブジェクト対応にしたいと思い、試行錯誤したサンプルです。
可読性の悪い既存のソースを可読性のよいオブジェクト対応にしてみました。サンプルに取り上げたソースはGoogleブログで構築した自前のサイトです。このブログサイトにある目次処理のソースコードをオブジェクト対応にしてみました。
# 目次について
目次処理しているソースを開発エディターで見渡してどこをどうオブジェクトにするかの見当をつける。
目次処理に必要なデータは、ブログの全投稿データで、そのデータから目次に必要なデータを抽出して目次データを作っています。
その処理をどこで行っているかを調べます。

ブログの目次は何のために作ったかと言うとそれは、ブログには元々アーカイブでブログ一覧がありますが、どちらかと言うと少々、わかりづらいため、もう少し、見やすいブログ一覧を作りたいということからです。

目次のあるサイト
https://tecoyan.blogspot.com/#main
このページのサイドバーにある「〇人生の応援歌」が目次になります。ここの処理をオブジェクト対応します。オブジェクト対応前のソースコードはまとまりがなくコードがあっちこっちに点在するため、ここには記載していません。
# 作業の進め方
まず、オブジェクト対応にするため、目次処理作業を言葉で表現してみます。
(1)ブログの全投稿データをGoogleブログサイトから取得します。
(2)取得した投稿データを元に目次を生成します。
(3)生成した目次データをデータベースに保存します。
(4)データベースから目次データを取得し画面に表示します。

以上の処理コードをオブジェクト化します。オブジェクトにはプロパティデータとメソッドがあります。既存のソースコードで使用しているデータ(変数など)はプロパティデータに入れます。更に既存のソースコードの関数はメソッドとして作成します。上記の説明から、メソッドは以下の4つ作成します。
(1)getPost()
(2)create()
(3)save()
(4)display()

今回、作成するオブジェクトの名前は、Mokujiとします。
オブジェクト構造の大枠は、以下になります。
let Mokuji = {
        ・・・・・・　　　//プロパテイ定義データ
    //以下はメソッド定義
    getPost: function(){},
    create: function(){},
    save: function(){},
    display: function(){},
    expand: function(){}　　　//目次を展開するメソッド
};

# データの入出力関係
目次データの元データはブログの投稿データです。そのデータを加工して目次データを生成し、Mokujiオブジェクトのバッファへ一時保存します。一時保存したデータはデータべースへ永久保存します。最後に、データベースの目次データを画面に表示します。

メソッド別の入出力データ
(1)getPostメソッド　 (入力元)ブログ　(出力先)Mokujiオブジェクト(投稿データ)
(2)createメソッド　　(入力元)Mokujiオブジェクト(投稿データ)　(出力先)Mokujiオブジェクト(目次データ)　　　　   
(3)saveメソッド　 　(入力元)Mokujiオブジェクト(目次データ)　(出力先)データベース
(4)displayメソッド　(入力元)データベース　(出力先)画面

メソッドを4つに分けましたが、他でも使えるのは、getPost()、display()です。
createメソッドとsaveメソッドは一体のもので、単独で使うにはあまりメリットはありません。一つにしてもいいかもしれません。
いずれのメソッドもMokujiオブジェクトと一体です。
# 他からのアクセスのための干渉問題
(1)目次表示関数は2つのjavascriptファイル(blog_script_body.js,blog_side_bar.js)から呼び出しています。オブジェクト化したのは、blog_side_bar.jsにある目次関数です。そのため、もう一方のblog_script_body.jsから呼び出している目次関数の箇所をMokuji.xxxxx()と変更しなくてはなりません。ここを変更し忘れると、undefinedのエラーが出ます。
(2)blog_side_bar.jsにある他の共通関数の呼び出し
今回のオブジェクト化は、まず先に、blog_side_bar.jsにあるコードを一括してMokujiオブジェクト変更しました。関数はすべて、xxxx:function(){},形式に変更しました。変数もすべて、xxxx:"",形式にしました。
まず先に、全体の形式を整えました。そこで、この中にあるメソッドで目次処理以外のメソッドも含まれていますので、それらは、元の関数形式にもどしました。変数も同様にもどしました。
(3)イベント処理関係
$(document).ready(function () {・・・のような、イベント処理らは、Mokujiオブジェクトから除外し、オブジェクトの外側におきました。
(4)use strict対応
コードの先頭に'use strict';文を置き、変数、メソッドのundefinedエラーを見つけます。この状態で、サイトのページを実行すると、このundefinedエラーが頻繁に発生します。それらは、ひとつづつつぶしてゆきます。面倒ですが、仕方がありません。
(5)$.each(xxx,function(i,val){.....})の中のthis使用で
{}内で、thisを使用すると、このthisはMokujiオブジェクトを参照していません。xxxで指定した配列要素のオブジェクトを参照しています。
そのため、ここは、thisを使用しないで、Mokujiを直接指定しています。
このように都度の実行で、エラーを見つけ、ひとつづつエラーをつぶしてゆきます。
# 変更後の実行結果
一通りのオブジェクト化が終了したので、実行してみました。
いくつかの問題はありましたが、まずは一応、目次生成した結果が画面に表示されました。
# あとがき
今回は、既存のコードを変数を含めてここにオブジェクト対応して行くことは骨が折れると思い、ソースの置換を用いてソースコード全体を一括変更しました。そのあとに個別の変更を加えて行きました。一通りの変更を終えた後は、実行してエラーを出し、それらの不具合をつぶしてゆきました。
この方法で比較的早く、完成に近づけました。
(追記)
実は、メソッドの分割は上記のように4つにはなっていません。既存のソースコードをそのまま使っていますので、アイディア通りにするには、もう少し後になります。ご了承願います。

# 裏情報
このコードは、みっともなくて人さまにはお見せ出来ませんが、Chromeデバッガーを開いて、ソースタブのblog_side_bar.jsファイルを開くと見ることができます。デベロッパーの方ならいつも行っていることですね。
オブジェクト化の苦労の跡が垣間見れると思います。
【Vue.js】SVGをコンポーネント化する方法

自作のSVGファイルをコンポーネントとして使いたくなる場面があるかもしれません。

# 方法その１　普通にやる
SVGをそのままtemplateに書いてしまえばコンポーネントとして使うことができます。

```vuejs:components/icons/logo.vue
<template>
  <svg xmlns="http://www.w3.org/2000/svg">
    <!--何か -->
  </svg>
</template>
```

```vuejs:App.vue
<template>
  <icon-logo />
</template>

<script setup lang="ts">
import IconLogo from './components/icons/IconLogo.vue'
</script>
```

これで表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247330/181103ec-2db0-df3f-de18-b3d5889326ef.png)

# 方法その２　unplugin-icons
先の方法だと、わざわざSVGファイルを開いてcomponents内にコピペする必要があるため、なかなか面倒です。
そこで、[unplugin-icons](https://github.com/antfu/unplugin-icons)というパッケージを使う方法を紹介します。

まずはインストール
```
npm i -D unplugin-icons
```

次に設定ですが、今回はViteでやってみます。
```typescript:vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Icons from 'unplugin-icons/vite'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'

export default defineConfig({
  plugins: [
    vue(),
    Icons({
      customCollections: {
        svg: FileSystemIconLoader('src/assets/svg')
      },
    })
  ]
})
```

これで、`src/assets/icons/`ディレクトリにSVGファイルを配置するだけで、コンポーネントとして呼び出すことができるようになります。
`~icons/icons/<ファイル名>` としてimportすることができます。

```vuejs:App.vue
<template>
  <icon-logo />
</template>

<script setup lang="ts">
import IconLogo from '~icons/icons/logo'
</script>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247330/f943f17e-08da-304e-67a9-52b24f91950d.png)

設定したディレクトリにファイルを置くだけで使えるので、なかなか便利です。
[unplugin-icons](https://github.com/antfu/unplugin-icons)には他にも色々な機能があるので、是非調べてみてください。
オリジナルアプリのコメント機能を非同期で投稿出来るように変更した時の備忘録

オリジナルの写真と投稿アプリを作成した時にコメント機能に後からAjaxで実装してみようと思ったらかなり手こずったので忘れない為に備忘録を残します。
投稿した写真にログインしたユーザーがコメント出来る機能になってます。


### コントローラーの編集
投稿した写真の詳細ページにコメントしたいのでアクションはcreateとdestroyの二つ
画面遷移はしたくないのでrenderやredirectの記述はしない
@comment = Comment.find(params[:id])をdestriyメソッドの下に書くと意味がないので一番上に記述する
```:comments_controller.rb
 def create
    @post = Post.find(params[:post_id])
    @comment = Comment.new(comment_params)
    @comment.save
  end

  def destroy
    @comment = Comment.find(params[:id])
    @post = Post.find(params[:post_id])
    @post_comments = @post.comments
    Comment.find_by(id: params[:id], post_id: params[:post_id]).destroy
  end

  private
  def comment_params
    params.require(:comment).permit(:text).merge(user_id: current_user.id, post_id: params[:post_id])
  end
```

### フォームの編集と部分テンプレートの追記
form_withのlocalオプションをfalseにする
投稿したコメントを表示するための部分テンプレートを挿入
```:show.html.erb
 <%= form_with model: [@post, @comment], local: false do |f|%>
      <div class="post-field">
         <%= f.label :text, "コメント" %>
         <%= f.text_area :text, class: :post_text_field %>
      </div>
     <div class="show__comment__actions">
       <%= f.submit "コメントを投稿する", class: :comment_form__btn  %>
    </div>
 <% end %>

<ul class="show_comments_lists">
    <%= render "comments/comments", post: @post, comments: @comments %>
</ul>
```

### 投稿したコメントを表示するための部分テンプレートを作成
link_toにはremote: trueを追記する
```:_comments.html.erb
<% post.comments.each do |comment| %>
  <li id="comment_<% @comment.id %>" class="show_comments_list">
     <%= comment.text %><br>
     by@<%=  comment.user.name %>
      <% if user_signed_in? && current_user.id == comment.user_id  %>
       <%= link_to "コメントを削除する", post_comment_path(comment.post, comment),  method: :delete, remote: true, class: :post_delete_btn %>
       <% end %>   
  </li>
<% end %>
```
＊ここで注意なのがidの指定に<% @comment.id %>を記述すること。削除機能を実装する際に重要になる。

下準備が終了したのでAjaxでの投稿機能と削除機能を書いていく


### コメントを投稿するためのJavaScriptファイルを作成
```:create.js.erb
$("textarea").val('');
$('.show_comments_lists').html("<%= j(render 'comments/comments', post: @post, comment: @comment) %>");
```
*コメントが投稿された後にフォームを空にしたいのでtextareaのvalue属性をval('');と記述
コメントを表示するためにhtml()を記述してrenderで指定した部分テンプレートに更新させる。（jはescape_javascriptの略）


 ### コメントを削除するためのJavaScriptファイルを作成
```:
$('#comment_<%= @comment.id %>').remove();
$('.show_comments_lists').html("<%= j(render 'comments/comments', post: @post, comment: @comment) %>");
```
ここが一番手間取った…
remove()にshow_comments_listsを指定するとコメントが全て削除されるのでcomment_<%= @comment.id %>を指定。
@comment.idはコントローラーにdestroyアクションに@comment = Comment.find(params[:id])を記述しているから使える（まずこれを書いていなかったのでエラーが発生しまくった）

あと勘違いしていたのがremove()。てっきり削除した上で画面の表示を変えてくれるのかと思ってたら削除しかしないメソッドだった。
なのでcreate.js.erbと同様にrenderで指定した部分テンプレートに更新させるための記述を追記　。


以上でAjax化終了
参考になる記事があった上で実装にかなり手間取ったのでコントローラーでの変数の指定する際の意味やメソッドの特性をもっと知るべきだなと感じました。

参考にさせて頂いた記事はこちらです。
https://qiita.com/coneco12_/items/61174a80a611b7e0049e
Windows10またはWindows11でノートパソコンのカバーを閉じた時の動作設定（スリープしなように、など）

# やり方

コントロールパネル⇒ハードウェアとサウンド⇒電源オプション
**カバーを閉じたときの動作の選択**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d1efcd08-d4eb-67ba-dfba-e50d81c23c82.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f95a419b-c636-3e7e-bc74-8dd95fc42ac9.png)

選択肢は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/02e33a3f-1906-04aa-fbc8-c2b1b770c664.png)

『変更の保存』を押せばすぐに反映される。
再起動の必要は無し。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a51388a2-0aef-3ab1-e07c-fc4de0e17ba4.png)


# 参考サイトさん

https://tokusengai.com/_ct/17354769

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
Microsoft Windows [Version 10.0.22631.3810]
メソッド の 定義 と 戻り値

# 目的
- メソッド の 使い方 を 理解する

# ポイント
- メソッド とは まとまった一連の処理 のこと
- メソッドの最後に処理した値は呼び出し元に戻される

# 書き方の例
```ruby
def buy_fruits

  apple = "apple"

  if apple == "apple"
    puts "りんごを渡す"
  elsif banana == "banana"
    puts "バナナを渡す"
  elsif lemon == "lemon"
    puts "レモンを渡す"
  end
end

buy_fruits
```
~実際の表示~
りんごを渡す
# 注意するポイント
- 「puts」という命令の戻り値は nill となる

# 具体的な例
- 上記の例に apple という 戻り値を返すようコードを追加する
```ruby
require "pry"

def buy_fruits
  apple = "apple"

  if apple == "apple"
    puts "りんごを渡す"
  elsif banana == "banana"
    puts "バナナを渡す"
  elsif lemmon == "lemmon"
    puts "レモンを渡す"
  end

  apple

end

binding.pry

buy_fruits

```
~実際の表示~
 34: 
    35: end
    36: 
    37: binding.pry
    38: 
 => 39: buy_fruits

[1] pry(main)> buy_fruits
りんごを渡す
=> "apple"
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その019

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: 構成、設定とオブジェクト
オブジェクトマネージャと Lightning アプリケーションビルダーの確認
　にある練習問題７問目をご紹介します。
https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-setup-and-objects/practice-user-setup

なお、こちらの内容はYouTubeでも公開しております

https://www.youtube.com/watch?v=gMBC6yCVX_8&t=52s

<iframe width="560" height="315" src="https://www.youtube.com/embed/gMBC6yCVX_8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


オブジェクトマネージャと Lightning アプリケーションビルダーの確認
練習問題7問目はこちらです

![００７.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4b9585ab-4f50-1350-7c43-278a65da5bb7.png)


選択リストの項目値ごとに色を設定したい　という問題ですね

正解はCとD
でした

Cについて
選択リストの設定から「どの値がどの色か」の設定が可能です
詳細は以下ヘルプをご確認ください

https://help.salesforce.com/s/articleView?id=000329177&type=1

Dについて
選択リストの値ごとにIMAGE関数で色を付ける方法はヘルプでも紹介されていますね

https://help.salesforce.com/s/articleView?id=sf.useful_advanced_formulas_image_links.htm&type=5

特定の選択リストで特定の色の画像を出すことは可能です
IMAGE( 
CASE( Priority, 
"Low", "/img/samples/flag_green.gif",
"Medium", "/img/samples/flag_yellow.gif",
"High", "/img/samples/flag_red.gif", 
"/s.gif"), 
"Priority Flag")

ではAが間違っている理由を説明します
Aのバケット項目とは選択リストに対してグループ化できる設定です
なので今回のように色の設定はできないので間違いです

Bが間違っている理由について説明します

Bの条件強調表示は数値項目について使える設定ですね

なので今回のようにフェーズのような選択リストでの設定はできないので間違いでした

今日の内容はここまでです。
皆さん楽しく元気にSalesforceを学びましょう！
CLOVA Speechを学んでみた

Digital Hack Day2022の提供技術のひとつである**CLOVA Speech**について学んだことメモ

# CLOVA Speechとは
**LINE**が独自に開発した人が**話す言葉**を**文字に変換する**技術のこと
様々な環境下で、世界最高レベルの音声認識ができる

## 実現できること
1. リアルタイムのストリーム音声解析
1. 長時間の音声データ解析
1. 専用ビルダーでカスタマイズ可能
1. APIでたシステムと簡単に連携
1. CLOVA Text Analytics等との連携

## 活用例
* コールセンターにおけるオペレーター対応サポート
* テレビ番組のリアルタイム字幕起こし
* 議事録の作成
* 運転中の音声操作

## 高精度の音声認識を実現する技術
### End-To-End音声認識
音声データを1つのNeural Network(E2Eモデル)で処理してテキストにする
* 目指す出力になるよう直接モデルを学習できるため、**精度が高い**
* 研究が盛んで技術進展が**著しい**
### 自己教師あり学習
音声データから独自のラベルを機械的に作り、学ばせる
人間の音声言語獲得の手順に近い
* 音の性質を熟知した状態で本当に説きたい問題の解放を学ぶことで、**より精度を高められる**

# 参考
https://clova.line.me/clova-speech/

https://youtu.be/F1TQEUKaHw8?t=6296
ESXiをコマンドラインで操作する（Cheet Sheet）

# コマンド
|操作|コマンド|補足|
|:-:|:-:|:-:|
|VM一覧の表示|vim-cmd vmsvc/getallvms</left>||
|VMのパワーオン|vim-cmd vmsvc/power.on \<vmid\>|\<vmid\>はgetallvmsで確認する|
|VMのパワーオフ|vim-cmd vmsvc/power.off \<vmid\>|\<vmid\>はgetallvmsで確認する|
|VMのパワー状態|vim-cmd vmsvc/power.getstate \<vmid\>|電源状態（on or off）を得る|
|VMへの既存ディスク追加|vim-cmd vmsvc/device.diskaddexisting \<vmid\> \<disk_file\> \<controller_number\> \<unit_number\> [ctlr_type]|\<disk_file\>:追加するディスクのパス／\<controller_number\>:コントローラの番号／<unit_number\>コントローラに接続するデバイスのユニット番号／[ctlr_type]: コントローラタイプ（デフォルト : SCSI)|


# 確認環境と前提
* VMware ESXi 6.0 Update 2
* ESXiホストのSSH Shellを有効化していること

# 補足情報
* 筆者がよく使うものの忘れがちな`vim-cmd`コマンド操作の一覧です。既知の用法でコマンドの綴りやオプション・パラメータを確認することが目的です。コマンドを詳しく説明するものではない点、ご了承ください。
Rubocopに速度が早くなる「serverモード」ができたみたいなので試してみる ~RubyKaigi 2022に影響されるエンジニア~

## 概要
RubyKaigi2022の方に参加してきまして、様々な登壇者の発表を聞いてきました。
その中で、Rubocopの性能改善について話がありまして今の案件や過去の仕事で使っていたりしたので手元で動かして速度測ってみたくなったので動かしてみたという話です！

## そもそも何が変わったのか

前段として、そもそもどうして性能が変わったのかという点について説明しますと、Rubocopの方で「server-clientモデル」が実装されましてRubocop-serverを立ち上げておいて処理を実行することで高速化を行ったというものでした。
また、そちらがデフォルトになるわけではなく、モードの指定を行わないとRubocop-serverは起動されないのでそのあたりのオプションを試してみたいと思います。


## 動かして見よう

### 環境

Ruby 3.1
Rubocop 1.36.0

少し前から実装されてるモードなのでここまで新しくなくても良さそうですけど、今回はこれでやっていきます

(補足)
おそらくRuboCop 1.31でサーバーモードは導入されているらしく、そちらを動かすにはRuby2.6以上が必要みたいです。



### 速度測定方法について
時間の測定にはtimeコマンドを利用します。

| 項目 | 意味 |
|-|-|
|real|プログラムの呼び出しから終了までにかかった実時間（秒）|
|user|プログラム自体の処理時間（秒）（ユーザCPU時間）|
|sys|プログラムを処理するために、OSが処理をした時間（秒）（システム時間）|

↑
引用
https://qiita.com/tossh/items/659e5934e52b38183200


```
/usr/bin/time -p bundle exec rubocop ファイル名.rb
```
※Macの場合ただのtimeコマンドだと想定していた数値が出なかったので明示的に呼び出してます

### 通常起動
結果
```
real         1.24
user         0.90
sys          0.23
```
```
real         1.27
user         0.84
sys          0.24
```
```
real         1.21
user         0.84
sys          0.23
```


### server起動版
サーバーの起動
```sh
bundle exec rubocop --start-server
```
Rubocopの実行
```
/usr/bin/time -p bundle exec rubocop ファイル名.rb
```

```
real         0.81
user         0.52
sys          0.11
```
```
real         0.79
user         0.53
sys          0.11
```
```
real         0.75
user         0.52
sys          0.11
```
## まとめ

確かに2倍とまで行かないまでも1.5倍近く速度が変わることがわかった
すごい...
もっと大量のコードで試してみたい気持ちがありますが、手軽に試してちゃんと速度的成果がでているのがとてもすごいと思った。
［エラーメッセージ］”ActiveRecord::PendingMigrationError”解決までの流れ


# １．前提条件
#### 開発環境
Ruby：ruby 3.1.2
Rails：Rails 6.1.6.1
OS：Windows11 Home


# ２．エラーメッセージの内容

![error_img](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2823804/86d78dc1-3403-0fb3-1814-8ee88992c7f5.png)

#### ②エラーメッセージ翻訳
エラーメッセージを翻訳する
　
　”移行は保留中です。 この問題を解決するには、次を実行します。
　 bin/rails db: RAILS_ENV=development を移行
　 保留中の移行が 1 件あります:
　 20210727061455_create_books.rb”

#### ③エラーの原因を考える　(※考えられる原因は随時追記することとする。)
今回のエラーはmigrateし忘れているというものである。
考えられる理由を下記に記述する。

　・単純にrails db:migrateし忘れている



# ３．エラーの解決方法

#### ①ターミナルにマイグレーション実行の下記のコマンドを打ち込む

```
$ rails db:migrate
```

#### ②ブラウザにて、エラーが解除されていることを確認する
　※解除されていない場合、ほかの原因を探る

# ４．参考サイト

（railsガイド）：　https://railsguides.jp/active_record_migrations.html

https://www.sejuku.net/blog/14229
Linux MTAについて（自分用メモ

●メール配送エージェント
・MTA（Mail Transfer Agent）
メールの転送を行うプログラム。ネットワーク経由、またはサーバ内部（ローカル）のメール転送依頼に基づき、指定された宛先へメールを転送する。MTAはSMTPサーバとも呼ばれる。

・MDA（Mail Delivery Agent）
ローカルのメールスプールへ配送するプログラム。MTAによってローカルの宛先へのメールであると判断されたメールを受け取り、宛先ユーザのメールボックス（メールスプール）へメールを配送する。

・MUA（Mail User Agent）
ユーザーがメールを扱うプログラム。自身のメールボックスへアクセスして受信したメールを閲覧したり、メールを送信したりする。LinuxのmailコマンドやThunderbird、WindowsやMac OS X付属のメールソフトがある。

●代表的なMTA
・Postfix sendmailとの高い互換性を持ちながら、処理を高速化している。設定がわかりやすくセキュリティが向上しているため、近年一部のLinuxディストリビューションでは照準のMTAになっている。

・exim Debian系の標準MTA。設定はわかりやすいが、日本語の情報が比較的少なく、設定ファイルの内容はバージョンによって異なる。

●mailコマンド
メールの送信や、受信メールを表示する

mail [-s 件名] [宛先メールアドレス もしくは ユーザ名]

オプションを付けずに「mail」コマンドを実行すると、メールスプール「/var/spool/mail/」に格納されている受信メールを表示

●mailqコマンド
メールキューにメールが溜まっているかを確認できる

MTAには、ローカル宛として扱う宛先を実際のユーザとは異なる別名で作成し、受信した宛先とは異なる複数のユーザーや外部の受信者宛に転送する機能がある。

Postfixでは別名（エイリアス）を「/etc/aliases」に記載し、newaliasesコマンドで別名をPostfixに認識させることで、メール転送を有効化することができる。
複数の宛先を指定する場合はカンマで区切って指定。

別名:転送先（メールアドレスやアカウント）[,転送先（メールアドレスやアカウント）,転送先（メールアドレスやアカウント）...


「/etc/aliases」はMTAに対する設定のため、各ユーザが個別にメール転送する目的には使用できない。各ユーザごとのメール転送設定は、ホームディレクトリの「.forward」ファイルを使用する。「~/.forward」ファイルには別名を使用することはできないが、そのユーザ宛に届いたメールを異なる複数のユーザーや外部の受信者宛に転送する事ができる。転送先が複数ある場合は、改行で区切って指定。
「~/.forward」ファイルの設定変更は即時有効になる。