OmniAICreator/Qiita-1.07M huggingface dataset:
Prism 8 と DryIoc 5 は共存できない

WPF+Prism アプリケーションを作るとき、DIコンテナーは UnityContainerかDryIoc の二択で(Autofac対応はずいぶん前に削除された)、nuget からは Prism.DryIoc パッケージを追加すればいいのだけれど、ロギングその他をDI経由で使う場合に 以下のようにすることとなる

```csharp
class App{
        protected override IContainerExtension CreateContainerExtension()
        {
            var services = new ServiceCollection();
            services.AddLogging(loggingBuilder =>
            {
                loggingBuilder.ClearProviders();
                loggingBuilder.SetMinimumLevel(LogLevel.Trace);
                loggingBuilder.AddNLog();

            });

            var container = new DryIoc.Container(CreateContainerRules())
                       .WithDependencyInjectionAdapter(services);
            return new Prism.DryIoc.DryIocContainerExtension(container);
        }

}
```

これを実行すると以下のような例外が発生する。

```
System.MissingMethodException: 'Method not found: 'DryIoc.Rules DryIoc.Rules.WithoutFastExpressionCompiler()'.'
```

これは Prism.DryIoc 8 が DryIoc 4 をベースにしており、その DryIoc 5 から `WithoutFastExpressionCompiler` が削除されているから。

したがって 一旦 Prism.DryIoc 8 をインストールした後 DryIoc を 4 系列に更新する必要がある。
Rubyの基礎概念をまとめてみる

プログラミングを独学で学んできましたが
転職活動を通じて、Rubyの基礎概念の知識が不足していると感じたので、あらためて勉強をしなおしています。

アウトプットのために、Rubyの基礎概念をまとめてみます
（他毎日30分　Rubyのコードを書くようにしています）

## オブジェクト指向とは

rubyはオブジェクト指向と言われているが、オブジェクト指向とはなんだろうか？

- オブジェクトとは”もの”
- オブジェクトを作ったり、使ったりすることでプログラマの望んだ処理を行わせる言語
- クラスという設計図を使って”new”で「もの」＝インスタンスを作ることができる
- 自分で作らなくても、はじめから存在する「もの」もあり、文字クラスとか、整数クラス、日付クラスが代表例　

## Class
自分でClass＝設計図を作れる。　
クラスもオブジェクトになる
User情報なら　
- name
- address
- e-mail
など色々あると思うので、そのような情報を持てる

```Ruby
class User
　　　　# 処理
end

```

## インスタンス
インスタンスとは、事実、事例などをもつという意味。プログラミング言語では**実態**と訳されるらしい
（インスタントラーメンっていうし”簡単な”とか"即席の"とかの意味だと勝手に思っていました...恥ずかしい..）
Class（設計図、工場）からインスタンスが作成できる　

```Ruby

user = User.new

```

## initialize
設定しておくと、classからインスタンスを作成するときに自動的に実行してくれる便利なもの

```Ruby
class User
    attr_reader :name, :address ,:email
    def initialize(name,address,email)
        @name = name
        @address = address 
        @email = email
    end
end
```

実行
```Ruby
user = User.new("kiyoma",chiba,nil)
```

上記の例は、インスタンス生成時にインスタンス変数を設定している


## getter/setter

一時的にオブジェクトの抱えるデータのことを **属性(attribute)** という
先程の例でいうnameやaddressのこと　

getterとは、通常インスタンス変数はクラス内でないと参照できないが、クラス外でも参照したいときに使うメソッド
setterとは　、クラス外でインスタンス変数の値を変更したいときに使うメソッド

```Ruby
class User
# getterメソッド
 def name
    @name
 end
# setterメソッド
def name（name）
    @name = name
 end
end
```

わざわざ上記のように書かなくても簡略的にかけるメソッドもある
| メソッド | 役割 | 
|:-----------|------------|
|attr_reader|getterと同じ　　クラス外で参照可能|
|attr_writer|setterと同じ　クラス外から更新可能|
|attr_accessor|setterとgetterの役割　クラス外から参照＆更新可能|

```Ruby
class User
  attr_accessor: :name,:address,:email
end
```
こうしておくと
```shell
> user=User.new
> user.name="kiyoma"
=> "kiyoma"
> user.address="chiba"
=> "chiba"
```

というふうにオブジェクトが利用できる

## クラスメソット、インスタンスメソッド
これは転職活動中に聞かれたことですが、答えられなかったものです。

インスタンスメソッドは、インスタンスに対して実行するもの

```Ruby
class User
    def show
        @users
    end
end
```

```ruby
users=User.new
users.show
# インスタンス名.メソッド名
```

よく見る形です。

対してクラスメソッドは、クラス（設計図）に対して呼び出すもの

クラスメソッドを記述する方法は　selfをつけて定義するのが一般的らしいです

```Ruby
class Tax
    def self.rate
        1.1
    end
end
```

```Ruby
Tax.rate
# クラス名.メソッド名
```

Railsでよく見るモデルでの記述が実はクラスメソッドだったようです

```user.rb
class User < ApplicationRecord
  has_many :groups
end
```

クラスメソッドの使う機会は今はよくわかりません。
一般的に
- クラスメソッド　全体で扱うべき情報を扱う
- インスタンスメソッド　個々で扱うべき情報を扱う

らしいです。


## private
　　オブジェクトの内部からは利用できるが、外からは利用できなくなります。

```Ruby
class User

# privateの記述以降がprivateメソッドになる
 private
　　　　　def name
    @name
  end
end
```

```shell
>user = User.new
>user.name 
# エラーになる 参照できない
```

## インスタンス変数とローカル変数

- その場限りの一時的な変数　他のメソッドから使うことができない
- オブジェクト自体が保持する変数　オブジェクトのどのメソッド内からも使える

ローカル変数の例

```Ruby
class User
  def greeting(name)
    name = name
    "My name is #{name}"
  end
end

user = User.new("kiyoma")
user.greeting
# => Myname is kiyoma
```

他のメソッドからnameが使えない

インスタンス変数の例

```Ruby
class User
  def initialize(name)
    @name = name
  end
  
  def greeting
    "My name is #{@name}"
  end
end

user = User.new("kiyoma")
user.greeting
# => Myname is kiyoma
```

他のメソッドからnameが使える

以上
React Native ExpoでGoogle認証(Firebase)を実装する

今回は、FirebaseAuthenticationを使ってユーザー認証~with Google編~を記しておきます。

基本的には[公式ドキュメント](https://docs.expo.dev/guides/authentication/#google)通りです。

また、今回はiOSのみの対応で、デバッグ用のクライアントにはExpo Goは使わず、`dev-client`を使用する前提です。

## OAuth2 クライアントIDを作成する
https://console.developers.google.com/apis/credentials ここから作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/e0563235-be0c-8e0a-a69e-449db412c815.png)

例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/3589c7f8-6e6e-8425-72d3-1e8fd3571626.png)

作成後に発行されるクライアントIDを控えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/295869ec-8ae6-3cdf-efce-6131ba28fd24.png)


> 💡 バンドルIDは`app.json` もしくは `app.config.ts`の`ios.bundleIdentifier`と同一である必要があります。

## 必要なパッケージ(依存関係)をインストール
```
yarn add expo-application expo-auth-session expo-random
```

## コード例
```typescript
import { GoogleAuthProvider, onAuthStateChanged, signInWithCredential } from 'firebase/auth'
import * as Google from 'expo-auth-session/providers/google'
import * as WebBrowser from 'expo-web-browser'
import { useEffect } from 'react'
import { auth } from '@/libs/firebase/firebase'
import Constants from 'expo-constants'

WebBrowser.maybeCompleteAuthSession()
const useAuth = () => {
  const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
    iosClientId: `${ここに上記で控えたクライアントID}`,
  })
  onAuthStateChanged(auth, (user) => {
    if (user != null) {
      console.log('We are authenticated now!')
    }

    // Do other things
  })
  const signOut = () => {
    auth.signOut()
  }
  useEffect(() => {
    if (response?.type === 'success') {
      const { id_token } = response.params

      const getCredential = GoogleAuthProvider.credential
      const credential = getCredential(id_token)
      signInWithCredential(auth, credential)
    }
  }, [response])

  return { request, promptAsync, signOut }
}

export default useAuth

```

適当なコンポーネントから`promptAsync`を呼び出せば、お馴染みのGoogle認証画面に遷移し、認証が完了すると、`id_token`が取得され、FirebaseAuthでアカウントが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/544fd920-0d14-82b1-a36f-4c773949f557.png)

Firebaseの`signInWithCredential`を呼んであげればログイン状態にできます。
あとはFirebaseAuthenticationのドキュメント通りログアウトする処理をしたり、storeにユーザー情報を保持したり、自由に扱えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/57da25cd-68a7-e497-3fe9-bf60f3da4bff.png)

## 疑問
Javaの学習　~import~

前回に引き続き、Javaの学習まとめです。

### importとは
importを宣言することで、前回学習したようなpackageのクラスを簡単に利用できるようになる他、
Javaに元々用意されているパッケージ(クラスライブラリ)を利用できるようになる。

### importの宣言方法
この宣言をすることで、ソースコードをわざわざ完全修飾クラス名で利用しなくてもよくなる。
```java
import パッケージ名.クラス名;
```
クラスライブラリの場合も宣言方法は同じです。
アスタリスクを使うことで、一度に複数のクラスをインポートすることができます。
※サブパッケージであるjava.util.regexパッケージやjava.util.loggingパッケージに属するクラスはインポートできません！

また、頻繁に利用されるjava.langパッケージはインポート宣言を省略することができます。
```java
import java.util.Scanner;
import java.util.Date;
import java.lang.String; //省略可
import java.lang.Integer; //省略可

//java.utilパッケージに属する全クラスのインポート宣言
import java.util.*;
```

### まとめ
クラスライブラリにどのようなものがあるのか今度調べて見たいと思います！閲覧いただき有難うございました！！
削除機能：destroyがうまくいかなかった

Rais7系の不具合

行き詰まったことを書き出しています。

### 解決できなかったこと
削除を押下時に適切な挙動をするようにしたい。
現状、写真のような形です

Ruby on Railsで簡易的なWebアプリをつくっています。
railsのメッセージ投稿アプリ(CRUD処理の確認用)の箇所を作業しています。

削除の実装箇所がうまくいかず、困った。
具体的に言えば、作成したアプリで以下がうまくいかない
・投稿一覧から任意の削除ボタンをクリックすること
・投稿詳細に遷移するだけで削除ができないこと

原因の推測：
問題箇所を特定して、誤りがないか確認してみました。
コードには問題はなさそうでした。
理由を考えると以下の線が濃厚そうだった。
実際にバージョンを落として動かしてみます。その後、追記に書いてみようと思う。

参考:
https://qiita.com/jnchito/items/5c41a7031404c313da1f#link_to%E3%81%AEmethod%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9%E3%81%8C%E5%A4%89%E3%82%8F%E3%81%A3%E3%81%9F


削除機能にかかる箇所
```

1


app/views/posts/index.html.erbでの記述

<%= link_to "削除", post, method: :delete, data: { confirm: "削除しますか?" } %>
```
```
2

app/controllers/posts_controller.rbでの記述

     def destroy
     post = Post.find(params[:id])
     post.destroy!
     redirect_to post_path
end
vim  makeprog で ninja と make を自動で切り替えるメモ

## 背景

C/C++ プロジェクトで `Makefile` があれば make を呼び, `ninja.build` があれば ninja を呼びたい...

## 方法

vim-makeshift がありました!

https://github.com/johnsyweb/vim-makeshift

これで, `:lmake` or `:MakeshiftBuild` すれば `ninja.build` があれば ninja を呼んでビルドし, `Makefile` が あれば make を呼んでくれます!

筆者は `ctrl-m` にビルドのショートカットを割り当てているので, 以下のようになりました.

```
map <C-m> :<C-U>MakeshiftBuild<CR
```

`<C-U>` の意味はコチラ https://e-v-e.hatenablog.com/entry/20150101/1420067539
(ビルドのショートカットの場合は基本なくても大体大丈かなとは思います)

### 再度コンパイル時がうまく行かないとき

ソースとビルドディレクトリが分かれているとき, 一旦 makeshift でビルドし, エラーがあり quickfix でソースコードファイル開いた後だと次は実行に失敗したりします...

どうもそのときはソースコードを開いたディレクトリで make 関連のファイルを探索しようとしているようです.

```
let g:makeshift_use_pwd_first = 1
```

で解決できました. ビルドディレクトリ(vim を起動したディレクトリ)を優先して探索してくれます!

## その他

なんかちょっと make 起動までラグがあるっぽい?
javaScript_constructorメソッドを使って、DateやArrayの判別

```js
<body>
 <p id="test1"></p>
 <p id="test2"></p>
 <script>
  var dateTest = new Date();
  var arrayTest = ["i","am","array"];
  var pTest1 = document.getElementById("test1");
  var pTest2 = document.getElementById("test2");
  pTest1.innerHTML = isDate(dateTest);
  pTest2.innerHTML = isArray(arrayTest);

  // Date判別メソッド
  function isDate(date){
   var result = date.constructor.toString().indexOf("Date") > -1;
   return result;
  }

  // Array判別メソッド
  function isArray(array){
   var result = array.constructor.toString().indexOf("Array") > -1;
   return result;
  }
 </script>
</body>

// 結果
true
true
```
【Safari】MacとiPhone 実機で開発者ツールを使う方法

### 概要
iPhone 実機と Mac を接続して、Safari で開発者ツールの確認方法を説明します。

### 環境
macOS: Monterey
ver: 12.3.1

---

### 手順
#### 用意
-   接続ケーブル
-   iPhone
-   Mac

### iPhone 側

1.　iPhone の設定から「Safari」を選択
<img width="400" alt="sp1.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497584/71a9236c-a050-d0ee-58f2-8dab2bb14bb7.jpeg">

2.　下の「詳細」を選択
<img width="400" alt="sp2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497584/c685ce7c-b1bc-ffba-dfd9-7343df8e64d2.jpeg">

3.　「web インスペクタ」を ON に変更
<img width="400" alt="sp3.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497584/f63b6087-3279-18fa-2fd2-23ca375026cb.jpeg">

4.　確認したいサイトを Safari で表示
今回は以前に自分で作成した[日本百名山一覧](https://famous-mountains-in-japan.web.app '日本百名山')で確認します。
<img width="400" alt="sp3.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497584/a1b84485-4e33-228f-0fdb-86d76d4fae3f.jpeg">

#### Mac 側

1.　まず Safari を立ち上げて、
「環境設定」→「詳細」→ 「メニューバーに"開発"をメニューを表示」にチェックボックスをチェック
![pc2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497584/30cb5db6-7010-17d3-0026-b80cb90a7cef.jpeg)

2.　開発メニューから、接続している iPhone を選択し、確認したいリンクを選択
![pc3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497584/9900dbdd-a6af-ab11-7b02-e2bd36d6d44a.jpeg)

3.　開発者ツールが開き、こちらで確認
![pc4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497584/c17af056-b288-90a3-3cff-cbaf085befd0.jpeg)

4.　完了

### 参考

-   今回確認に使用したサイト
    [日本百名山一覧](https://famous-mountains-in-japan.web.app '日本百名山')
-   最近発見した Chrome の拡張機能（本記事とあまり関係ないですけど、すごく便利です。）
    [レスポンシブの確認が簡単に！ iPhone, iPad, Android など各モデルのサイズ、操作や動画にも対応した優れもの -モバイルシミュレーター](https://coliss.com/articles/build-websites/operation/work/mobile-simulator-for-responsive.html 'モバイルシュミレータ')
.Net 6: C# で JSON の Delete

.Net のバージョン

```text
$ dotnet --version
6.0.302
```

プロジェクトの作成

```bash
mkdir Delete01
cd Delete01
dotnet new console
```

フォルダー構造

```text
$ tree -L 1
.
├── Delete01.csproj
├── Program.cs
├── file_io.cs
└── obj
```

```cs:Program.cs
﻿// --------------------------------------------------------------------
//	Program.cs
//
//						Aug/07/2022
// --------------------------------------------------------------------
using System;  
using System.IO;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

// --------------------------------------------------------------------
namespace Update01
{
	class Program
	{
	static void Main(string[] args)
	{
		Console.Error.WriteLine("*** 開始 ***");

		string file_json = args[0];

		string	key_in = args[1];
		Console.WriteLine (key_in);

		string str_json = file_io.file_to_str_proc (file_json);

		Dictionary <string,Object> dict_aa = JsonSerializer.Deserialize
				  <Dictionary <string,Object>> (str_json)!;

		if (dict_aa.ContainsKey (key_in))
		{
		dict_aa.Remove (key_in);
		string str_json_out = JsonSerializer.Serialize(dict_aa);

		file_io.file_write_proc (file_json,str_json_out);
		}

	Console.Error.WriteLine("*** 終了 ***");
	}

// --------------------------------------------------------------------
	}
}

// --------------------------------------------------------------------
```

file_io.cs はこちら
[.Net Core で JSON の Update](https://qiita.com/ekzemplaro/items/69a27f453900f849da6d)

コンパイル

```bash
dotnet build
```

実行

```bash
bin/Debug/net6.0/Delete01 /var/tmp/json/tochigi.json t0925
```
学び

・wwwありとなしとは
「www」とは「World Wide Web（ワールドワイドウェブ」の略称
「http(s)://www.~」がwwwあり
「http(s)://~」がwwwなし

・SSLとは
「SSL」とは「Secure Socket Layer（セキュアソケットレイヤー）」の略称
WebサーバとWebブラウザとの通信においてやりとりされるデータの暗号化をする
テスト74

```vb

Public Sub PDF分割()
'-----------------------
'参照設定：Acrobat(Adobe Acrobat 10.0 Type Library)
'有料のAcrobat Proを使えるようにしておく必要がある
'-----------------------
'主な参考サイト様(以下のサイト以外にもたくさん確認しました。)
'初心者備忘録beginner's memo
'https://www.ka-net.org/blog/?p=7293

'VBA(Excel)からAcrobat経由でPDFをプログラミング操作(OLE:IAC)する
'http://pdf-file.nnn2.com/?p=93
'-----------------------
'メモ
'業務上、PDF分割の処理が必要になった。しかし、上記のサイト様を含めて
'いろんなサイトを調べたり参考コードを試してみたが、そのままではどうしても
'処理できなかった(ページ数がカウントできない、ページ削除できない、エラーが出るetc・・・)
'そのため､色々試行錯誤したところ今回のコードでPDF分割できた。
'ポイントのひとつは分割処理の前に分割元のPDFファイルを開くこと。
'処理の内容は対象のPDFを1ページずつ分割する。...〆(･ω･＊)ﾒﾓﾒﾓ
'-----------------------
Dim jso As Variant
Dim i As Long
Dim fp As String
Dim fn As String
Dim FSO As Variant

Const PdfFilePath = "C:\Users\User\Desktop\VBA練習\PDF\分割\test.pdf"

Set FSO = CreateObject("Scripting.FileSystemObject")
'フォルダパスとファイル名取得
With FSO

    fp = Getfolpath(.GetParentFolderName(PdfFilePath))
    fn = .GetBaseName(PdfFilePath)
  
End With


Dim objAcroApp As New Acrobat.AcroApp
Dim objAcroAVDoc As New Acrobat.AcroAVDoc
Dim objAcroPDDoc As Acrobat.AcroPDDoc
Dim PageCount As Long
Dim Ret  As Long

'Acrobatを起動
Ret = objAcroApp.Show

'PDFファイルを開いて表示する(←Acrobatは開くが指定のPDFファイルまでは開かない)
Ret = objAcroAVDoc.Open(PdfFilePath, "")

'分割元のPDFファイルを開く(ここがポイント)
CreateObject("Shell.Application").ShellExecute PdfFilePath

'PDDocを取得
Set objAcroPDDoc = objAcroAVDoc.GetPDDoc

'ページ数を取得
PageCount = objAcroPDDoc.GetNumPages()


With CreateObject("AcroExch.PDDoc")

    If .Open(PdfFilePath) = True Then
    
        Set jso = .GetJSObject
        
        For i = 0 To PageCount - 1
        'ポイントは、分割元のPDFファイルを開いておく必要がある
'        (開かれていないと以下のコードの部分でエラーになってしまう)
            CallByName jso, "extractPages", VbMethod, _
                        i, i, fp & fn & "(" & i + 1 & ").pdf"
        Next
        
        .Close
    
    End If
  
End With


Set FSO = Nothing
Set objAcroApp = Nothing
Set objAcroAVDoc = Nothing
Set objAcroPDDoc = Nothing
Set jso = Nothing

MsgBox "処理が終了しました。", vbInformation

End Sub
Dockerでwebサイトを簡単にhttps対応させる

# はじめに
Webサーバのhttps対応、やっていますか？なんか面倒くさそうとか、証明書の取得をいちいち自分でやったりしていませんか？
そんな人のためにうってつけのものがあります。**https-portal**です。これを使えば、びっくりするくらい簡単にwebサーバをhttps対応させることができます。今回はそのhttps-portalの使い方を説明していきます。

# https-portalとは
webサーバを糸も簡単にhttps対応してくれる優れものです。証明書の取得もDockerコンテナ内で勝手にやってくれるので便利です。
中にはnginxとlet’s encryptも含んでいます。nginxが入っているということは当然ながらリバースプロキシとしても使えます。

# 導入の仕方
とりあえず適当なフォルダを作って、中にdocker-compose.ymlを作りましょう
```
mkdir hoge
cd hoge
sudo vim docker-compose.yml
```
中には以下の内容を記述。

```docker
version: "3"

services:
  https-portal: #https化。プロキシサーバー
    image: steveltn/https-portal:1
    container_name: web_https-portal
    ports:
      - 80:80
      - 443:443
    networks:
      - frontend
    restart: always
    volumes:
      - ./certs:/var/lib/https-portal
    environment:
# 本番運用するときはコメントアウトを外す
#      STAGE: 'production'
#ここにドメイン追加で捌ける
      DOMAINS: localhost -> http://web01:80
      STAGE: local

#Apacheを使う
  web01:
    image: httpd:2.4
    container_name: website
    networks:
      - frontend
      - webnet
    restart: always

networks:
  frontend:
  webnet:
```

volumeを設定していなかったら毎回証明書を発行してしまうので設定しておく。
DOMAINSのところで、localhostへのアクセスはApacheが起動しているweb01へ行くように設定。
apacheはデフォルトでは80番ポートで待ち構えているので80番ポートに転送するようにします。

ドメイン毎にアクセス先を分けたかったら、カンマで同じような記述をDOMAINSに追記してやればOKです。
次にSTAGEについてですが、
- ローカル環境(オレオレ証明書)：local
- 独自ドメインはもっているが本番ではない(オレオレ証明書)：staging
- 本番(実際に証明書を発行)：production

という感じです。localとstagingはオレオレ証明書になるので、アクセスするときに警告がでます。十分にこれらでテストをしてからproductionでちゃんとした証明書を取得するようにしましょう。

```
docker-compose up -d
```
コンテナを立ち上げて、上の例だとhttps\://localhostにアクセスすればApacheに接続できます。
立ち上げた直後はつながらない可能性があるので、ちょっと時間を空けます。

# 最後に
https-portalを使えば、面倒な手続きから解放されます。よいhttpsライフを・・・
【Swift】WKWebViewでGoogleログインが表示されない

# はじめに
私はWKWebViewでTwitterログインを実装しようと思ってログイン画面を表示しました。
そしたらなんとGoogleでログインがブロックされている！?！?！?！ってことに気づきました

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">WKWebViewログイン画面表示するとちゃんとGoogle要素ブロックされるのApple抜かりなくてウケる <a href="https://t.co/BhcbsMSWp3">pic.twitter.com/BhcbsMSWp3</a></p>&mdash; SNQ (@SNQ2001) <a href="https://twitter.com/SNQ2001/status/1554898491604074496?ref_src=twsrc%5Etfw">August 3, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

最初はAppleがGoogleをブロックしてる嫌がらせかと思ってました笑
しかし調べてみるとGoogle側がセキュリティ関係の問題で埋め込みブラウザでは表示できないようにしているようでした。

今回は埋め込みブラウザでも「Googleで続ける」を表示できるようにしていきます。

# 解決方法
```diff_swift
import UIKit
import WebKit

class ViewController: UIViewController {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        webView = WKWebView(frame: view.frame)

        view.addSubview(webView)

+       webView.customUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1"

        webView.load(URLRequest(url: URL(string: "https://mobile.twitter.com/i/flow/login")!))

    }

}
```

|通常|適用後|
|:-:|:-:|
|![simulator_screenshot_573B0F47-E41D-4D8B-929E-ABDED70D295B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/646ef65a-d6ec-3967-2529-424727342fe8.png)|![simulator_screenshot_E251749B-4F92-4663-B719-920F952FBD64.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d1f7ff49-2ad4-fe8e-92c9-59582358d3a8.png)|

# ユーザーエージェントについて
ユーザーエージェントについては詳しいことは分かりませんが、
サービスによっては変なユーザーエージェントを使用するとブロックされるなんてことも考えられます。

ユーザーの端末情報によって動的に変えられるように以下のような感じにしてみました。
```swift
webView.customUserAgent = "Mozilla/5.0 (\(UIDevice.current.userInterfaceIdiom == .phone ? "iPhone" : "iPad"); CPU \(UIDevice.current.userInterfaceIdiom == .phone ? "iPhone" : "iPad") OS \(UIDevice.current.systemVersion.replacingOccurrences(of: ".", with: "_")) like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1"
```
Safariのバージョン取得方法がわからなかったので15.0に固定しています。
iOSとSafariの対応表もあるっぽいのでそれを取得して動的に変更しても良さそうです。

なんの数字なのかわからない箇所もあるので完全とは言えませんが全部固定してるよりはマシだと思います。
これも動的に変更できるよってものがあればコメントで教えてください。

# 参考サイト
https://sussan-po.com/2019/11/22/wkwebview-user-agent/
vim で rust で build 結果の quick fix 表示やりたいメモ

vim で rust プロジェクトの quick fix(ビルドしてエラーでたらそのエラー場所に移動したりする)をやりたい...

一方で C++ quickfix の設定は残しておきたい...

## 方法

とりあえず rust プロジェクトに `.vimrc.local` を作り, それを読むようにします.

https://vim-jp.org/vim-users-jp/2009/12/27/Hack-112.html

空で `vim` を起動したときもローカルの vimrc 読みたいときは `BufEnter` も追加しておきます!

## ビルド設定

https://shinglyu.com/web/2016/12/25/vim-quickfix-for-rust-and-servo.html

'rust-lang/rust.vim' のプラグインは最新 vim(8.2)はもしかしたら標準で入っているかもしれません.

私は `ctrl+m` でビルド走らせるようにしているので, ローカルの vimrc は以下のような感じになりました.

```
".vimrc.local
compiler cargo

map <C-m> :make build<CR>

autocmd QuickFixCmdPost [^l]* nested cwindow
autocmd QuickFixCmdPost    l* nested lwindow
```

QuickFixCmdPost はお好みで...

![Screenshot from 2022-08-07 19-20-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/82fe6fa4-4f3c-84e0-8881-fb3d660dd5c3.png)


Voila!

## TODO

* https://qiita.com/hhatto/items/846defa92d9dfd446210 を試す
[windows]An error occurred while installing sqlite3 (1.3.13), and Bundler cannot continue.  In Gemfile:   sqlite3 解決方法

# 概要
Gemfile に ```gem 'sqlite3', '1.4.4'```を追記し、bundle install　したところ、遭遇したエラーです。MacやLinuxでの解決方法はかなりネットに出回っていたのですが、windowsでの解決法はほとんど見なかったので書き留めておきます。

**環境**
windows10
Rails 6.0.5.1
ruby 3.1.2p20

```powershell
PS C:\Users\glyce\rails_tutorial_2\hello> bundle install
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies.......
Using rake 13.0.6
（中略）
Using rails 6.0.4
Installing sqlite3 1.3.13 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
(中略)
An error occurred while installing sqlite3 (1.3.13), and Bundler cannot
continue.

In Gemfile:
  sqlite3
```
エラー文を読むに、sqlite3のgemをインストールできず、bundlerが続行不可になったようです。

# 事前準備

sqlite3が使えるか確認。
そもそもインストールや環境変数の設定に失敗している可能性を考えました。
```powershell
PS C:\Users\glyce\rails_tutorial_2\hello> sqlite3
SQLite version 3.39.1 2022-07-13 19:41:41
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
```
問題なさそうです。

# 解決方法
sqlite3のパスを指定したコマンドでインストールできました。
> gem install sqlite3 --platform=ruby -- --with-sqlite3-include=[path\to\sqlite3.h] --with-sqlite3-lib=[path\to\sqlite3.o]

上のコマンドに、sqlite3.exeが入ったフォルダのパスを当てはめます。私の場合はCドライブ直下だったため、以下のようになりました。
```powershell
PS C:\Users\glyce\rails_tutorial_2\hello> gem install sqlite3 --platform=ruby -- --with-sqlite3-include=/C/sqlite-tools-win32-x86-3390100 --with-sqlite3-lib=/C/sqlite-tools-win32-x86-3390100
Temporarily enhancing PATH for MSYS/MINGW...
Using msys2 packages: mingw-w64-ucrt-x86_64-sqlite3
Building native extensions with: '--with-sqlite3-include=/C/Users/glyce/soft/sqlite-tools-win32-x86-3390100 --with-sqlite3-lib=/C/Users/glyce/soft/sqlite-tools-win32-x86-3390100'
This could take a while...
Successfully installed sqlite3-1.4.4
Parsing documentation for sqlite3-1.4.4
Done installing documentation for sqlite3 after 0 seconds
1 gem installed
```
gemのインストールに成功しました！　ここでインストールされたsqlite3のバージョンが1.4.4だったため、Gemfileも```gem 'sqlite3', '1.4.4'```という記述に変更したところ、無事bundle install が完了しました。

# 参考
大変お世話になりました。ありがとうございます。
https://stackoverflow.com/questions/34171874/an-error-occurred-while-installing-sqlite3-1-3-11-and-bundler-cannot-continue
Linux find、locateコマンドについて（自分用メモ

●typeコマンドは、指定したコマンドが通常のコマンドか、シェルの組み込みコマンドか、エイリアスか、などの情報を表示します。通常のコマンドの場合、そのコマンドが格納された絶対パスを表示。


●検索用データベースを使用して高速でファイル検索を行うコマンドはlocate。

locateコマンドはあらかじめ作成された検索用データベースに沿って、検索パターンに合致したファイルやディレクトリを高速に検索。
なお、検索用のデータベースはupdatedbコマンドで更新します。また、updatedbコマンドの設定ファイルは「/etc/updatedb.conf」。


●updatedbコマンド
locateコマンドが利用する検索用のデータベースを更新します。
locateコマンドはあらかじめ作成された検索用のデータベースに沿って、検索パターンに合致したファイルやディレクトリを高速に検索します。
「/etc/updatedb.conf」ファイルでは、データベースに登録しない(locateコマンドでの検索対象外とする)ディレクトリの設定などを行うことが出来ます。
updatedbコマンドの設定ファイルは「/etc/updatedb.conf」。


●指定したコマンドの場所を検索するにはwhichまたはwhereisコマンドを利用。

whichコマンドは、環境変数PATHで設定しているディレクトリから検索します。
whereisコマンドは、Linuxでコマンドの格納される標準的なディレクトリの中から検索します。またマニュアル、ソースコードの場所も表示


●findコマンド
指定したディレクトリ以下からファイルやディレクトリを検索するコマンド。検索条件としてファイル名やディレクトリ名以外にも、アクセス権やファイルのサイズなど、さまざまな検索条件を指定できます。
※ただし、アクセス権がないファイルやディレクトリは検索できません。

find [検索起点ディレクトリ] [検索式] [アクション]

■検索式
・-name ファイル名　ファイル名で検索
・-atime 日数　最終アクセス日で検索
・-mtime 日数　最終更新日で検索
・-perm アクセス権　アクセス権で検索
・-size サイズ　ファイルサイズで検索
・-type ファイルの種類　ファイルの種類で検索(fはファイル、dはディレクトリ、lはシンボリックリンク）
・-user ユーザ名　ファイルの所有者で検索
・-maxdepth 階層数　指定した階層まで検索
・-mindepth 階層数　指定した階層から下を検索

■アクション
・-print 検索結果を改行で区切って表示（省略可能）
・-print0 剣閣結果をNULL文字(¥0)で区切って表示
・-exec コマンド名 {} ¥;　検索結果のファイルに対してコマンドを表示

※「{}」は検索結果のファイルに置き換えられます。また、「;」はコマンドの終了を意味します。「;」はメタキャラクタのため、シェルによって解釈されないよう「\」でエスケープします。


●FHS(Filesystem Hierarchy Standard：ファイルシステム階層標準)
ディストリビューションに依存しない、Linuxの標準的なディレクトリの構造を定めた規格のこと。

以前は各ディストリビューションが、それぞれに定めたディレクトリ構造を使用していました。そのため、インストールしたプログラムの配置場所がそれぞれのディストリビューションで違うなどの問題がありました。
このような問題をなくすために、どのディレクトリにどのようなファイルを格納するべきかということを標準化したのがFHS(ファイルシステム階層標準)です。

しかし、FHSではディレクトリ構造を詳細に規定しているわけではありません。また、あくまでもディレクトリ構造の標準ですので、各ディストリビューションがFHSに完全に従う必要はありません。
そのため、ユーザ自身がファイルの保管場所を検索、把握しなければならない場合があることに注意。
Linux tar,圧縮展開コマンドについて（自分用メモ

●cp [オプション] コピー元のファイル(ディレクトリ) コピー先ファイル(ディレクトリ)

オプション
-f コピー先の既存ファイルやディレクトリが上書きできない場合、削除してからコピーする
-i　同名のファイルやディレクトリがある場合、上書きするかどうか問い合わせる
-p　ファイルの属性（パーミッション、所有者、更新時間など）を保持したままコピー（所有者情報を保持できるのはrootユーザのみ）
-r|-R　指定したディレクトリ配下を全てコピー



●ls [オプション] [ディレクトリ名またはファイル名]

オプション
-a 隠しファイル（.ファイル）を表示
-A 「-a」と同じだが、カレントディレクトリと親ディレクトリは表示しない
-d 指定したディレクトリの情報を表示
-F名前の後ろのファイルタイプを表示
-i inode番号を付けて表示
-l 詳細情報の表示
-Rサブディレクトリの内容も再起的に表示



●rm [オプション] ファイルまたはディレクトリ名

オプション
-f 削除を問い合わせない
-i 削除を問い合わせる
-r|-R ディレクトリ全体を再起的に削除


●mkdir [オプション] ディレクトリ名

オプション
-m アクセス権　指定したアクセス権でディレクトリを作成
-p 引数に階層のあるディレクトリを指定した場合、存在しない中間ディレクトリも同時に作成


※rmdirは空のディレクトリのみを削除することができるが、-rオプションはありません。
※rmdirの「-p」はディレクトリ名に階層を指定した場合、全ての階層のディレクトリを同時に削除するオプションですが、空のディレクトリしか削除できません。



●tar [オプション] [ファイルまたはディレクトリ名]

オプション
-c 新しいアーカイブを作成
-x アーカイブからファイルを展開
-t アーカイブから内容を一覧表示
-f アーカイブファイル名を指定
-v 処理の詳細情報を表示
-z gzipを通して圧縮/展開
-j bzip2を通して圧縮/展開
-J xzを通して圧縮/展開

※tarコマンドではオプションの「-」は省略できます。オプションは順不同でも動作しますが、慣習的にはc, x, tのような動作オプションを先頭に指定します。

・bzip2よりも圧縮率が高い圧縮形式として、LZMA2圧縮アルゴリズムを採用したxzフォーマットがあります。xzはbzip2よりも多くのCPU／メモリを要求しますが、その分圧縮率が高く、また展開速度はbzip2より短いためファイル配布時の圧縮形式として採用されることが増えています。Linuxカーネルソースの配布形式としても採用されています。

●xz [ オプション ] 処理対象ファイル名

オプション
-d、—decompress 圧縮ファイルの展開
-k、—keep　圧縮、展開処理後に元のファイルを削除しない
-l、—list 圧縮ファイルの情報を表示する

オプション未指定の場合は、展開後元ファイルは削除されます。


例）アーカイブファイル「test.tar.xz」をカレントディレクトリに展開したい

・tar xvJf test.tar.xz
・tar xfJ test.tar.xz

または、
「test.tar.xz」は、拡張子が「tar.xz」であることから、複数のファイルがtarコマンドでアーカイブされた後、xzで圧縮されている事を示しています。 そのため、「test.tar.xz」ファイルは以下のように展開することも出来ます。

$ xz -dc test.tar.xz | tar xfv -

「test.tar.xz」ファイルは、tarでアーカイブしたファイル(test.tar)をxz形式で圧縮しています。はじめにxzコマンドで解凍し、解凍したファイルをtarコマンドに渡すことでファイルを展開することが出来ます。
xzコマンドの「-d」は圧縮ファイルの解凍、「-c」は標準出力に出力するオプションです。この場合、どちらも必須のオプションです。

標準出力に出力した内容(test.tarファイル)をパイプ(|)を使用して、tarコマンドの標準入力に渡しています。tarコマンドに渡された内容は既に解凍済ですので、「-J」オプションは不要です。
tarコマンドでのファイル名には「-」を指定します。これは標準入力からファイル名を受け取る事を意味します。


●dd [オプション]

オプション
if=入力ファイル　入力側ファイル（デバイス）を指定
of=出力ファイル　出力側ファイル（デバイス）を指定
bs=バイト数　入出力のブロックサイズ（一度に読み書きするバイト数）を指定。デフォルトは512バイト
count=回数　入力ファイルから出力ファイルへブロックをコピーする回数を指定

ddコマンドはデータをコピーするコマンド。
cpコマンドと異なり、ブロックサイズ(bsオプション)とそのブロックをコピーする回数(countオプション)を指定してファイルを作成することができます。
入力ファイル(ifオプション)に「/dev/zero」を指定すると全データがnullであるファイルが作成されます。「/dev/zero」はデータの上書きや、ddコマンドで内容の無い特定サイズのファイルを生成したい場合などに使用します。

例）「testfile」という5MBのファイルを作成する場合。(ブロックサイズは1MB)

$ dd if=/dev/zero of=testfile bs=1M count=5




●gzip [オプション] [ファイル名]

オプション
-d 圧縮ファイルを展開
-c 元ファイルを残して標準出力に出力
-r ディレクトリ内の全てのファイルを再起的にそれぞれ圧縮



●bzip2 [オプション] [ファイル名]

オプション
-d 圧縮ファイルを展開
-c 元ファイルを残して標準出力に出力


元ファイル残してファイルを圧縮するには「-c」オプションとリダイレクトの「>」を利用します。リダイレクトの「>」は標準出力の出力先を画面からファイルに切り替えます。
独習JavaScript（7章　スコープ）

# 独習JavaScriptのメモ
本は[こちら](https://www.shoeisha.co.jp/book/detail/9784798160276 "独習JavaScript")

## はじめに
* 今までJavaScriptは、ほぼ雰囲気で使っていた。が、ごまかしがきかなくなってきた。
* ので、（必要に迫られて）本書を手に取った。当初は基礎を総点検するのが目的だった。
* やり始めると知らなこと、理解が曖昧なモノが思いのほか多かった。なのでメモとして残す。
* 実務では利用しなさそうなモノもありそう。だが知識として残す。

### 7章　スコープ
多分ブラウザ前提のお話

#### スコープ種類
| 名前 | 概要 |
|:-|:-|
|グローバルスコープ|トップレベルにvarで宣言した変数、関数。|
|スクリプトスコープ|トップレベルにlet,constで宣言した変数、関数。|
|関数スコープ|関数内に宣言された変数。|
|ブロックスコープ|構文（ifやwhile文)などのブロック内でlet,constで宣言した変数、関数。|
|モジュールスコープ|ES　Modulesの機能が有効なときにトップレベルで宣言した変数、関数。|


#### グローバルスコープ、スクリプトスコープとWindowオブジェクト
グローバルスコープに属する変数や関数はWindowオブジェクトのプロパティやメソッドとして値が保持される。
同じくトップレベルにlet,constで宣言した変数、関数はWindowオブジェクトには保持されない。
```javascript:scope.js
// グローバルスコープ
function foo() {return "global function"};
var bar = "global value";

console.log(window.foo());
// ----->  global function

console.log(window.bar);
// ----->  global value

// スクリプトスコープ
const baz = function() {return "const baz"};
let qux = "let qux";

console.log(window.baz);
// -----> undefined
console.log(window.qux);
// -----> undefined
```

#### モジュールスコープ
モジュールスコープはscriptタグ単位のスコープになる。

```javascript:scope.js
// モジュールスコープ
<script type="module">
    var foo = "module foo1";
</script>

<script type="module">
    console.log(foo);
    // -----> ここでエラーになる。（グローバルスコープ、スクリプトスコープはエラーとならない）
</script>
```
#### クロージャ(Closure)
関数（オブジェクト）が状態を持つこと。通常は実行完了時にメモリ上から破棄される。
ただし、外部のスコープへの参照を持つ関数の場合は破棄されずメモリ上に保持し続ける。
このことをクロージャという。
ふーん、、くらいの感覚でしたが、目的が『カプセル化』と合って納得した。
```javascript:scope.js
function factory() { // 実行時にcountをインクリメントする関数を返す。
    let count = 0;
    return function increment() {
        console.log(++count) // レキシカルスコープのcountを参照している。
    }
}

const foo = factory();

foo();
// -----> 1
foo();
// -----> 2 countが1だった状態を持っているので++countは2となる
foo();
// -----> 3 countが2だった状態を持っているので++countは3となる ... （１）

const bar = factory(); // 関数初期化
bar();
// -----> 1 fooとは異なるオブジェクトなので4とはならず1となる。

foo();
// -----> 4 （１）の状態を保持しているので++countは4となる。barは関係ない。

```
wraptasでパンくずリスト

# はじめに
Notion+Wraptasでサイトをつくった場合、もちろん標準機能でパンくずリストは表示できますが、
私のサイトではDBのLinked viewを多用していたため、そのパンくずリストだといまいちわかりにくかったです。
ちょっと手間はかかりますが、自分で自由にパンくずリストつくることもできたので、その手順を書き残しておきます。


# どう実装した？
こんな感じ↓です。
https://haruchann.net/8c234db992af415aac973069df97102e
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779337/2c44d783-994f-0b3c-68b7-1c303c0a7afb.png)

# 手順
１．Wraptas管理画面＞サイトデザイン編集＞コンテンツエリア　にて、「コードブロックを使ったHTML挿入機能をONにする」にチェック

２．パンくずリストを挿入したい箇所にnotionのcodeブロック（言語：html）を挿入し、その中にパンくずリストのhtmlを記載する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779337/fadb1206-df03-3bc3-6b4a-4dbb42cdf701.png)

３．Wraptas管理画面＞サイトデザイン編集画面＞追加CSS　にて、デザイン編集

これでいい感じに表示されるはずです！

# サンプル
私のパンくず用HTMLとCSSを置いておきます。

~~~html:breadcrumb.html
<nav>
 <ul class="breadcrumb_list" itemscope itemtype="https://schema.org/BreadcrumbList">
  <li class="breadcrumb_item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="https://haruchann.net" itemprop="item">
      <span itemprop="name">トップ</span>
    </a>
    <meta itemprop="position" content="1" />
  </li>
  <li class="breadcrumb_item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="https://haruchann.net/us_exchange" itemprop="item">
      <span itemprop="name">Tech</span>
    </a>
    <meta itemprop="position" content="2" />
  </li>
  <li class="breadcrumb_item">wraptasでパンくずリスト</li>
</ul>
</nav>
~~~

~~~css:breadcrumb.css
/*■パンくずリスト*/
.breadcrumb_list{
  display: flex; 
  list-style-type: none; 
  padding:0px;
  color:gray;
}

.breadcrumb_list li a{
  padding: 5px;
  color: gray;
  text-decoration: none;
}

.breadcrumb_list li a:hover {
  color: black;
}

.breadcrumb_list li:after {
  content: '\003e'; /* 「>」を要素間の区切り文字として表示 */
  margin-left: 10px; /* 区切り文字と要素の間隔を調整 */
  margin-right: 10px; /* 区切り文字と要素の間隔を調整 */
  color: gray;
}

.breadcrumb_list li:last-child:after {
  content: ""; /* 最後のliの後ろには区切り文字を表示しない */
}
~~~

# 参考
https://technical-seo.jp/structured-data-for-breadcrumb/

https://public-constructor.com/breadcrumb-navigation-menu/
GA4が導入されているかを外側からチェックするブックマークレット（GTM利用サイトの場合）

今回は今閲覧しているサイトに、Googleアナリティクス4（GA4）が導入されているかどうかをチェックする【ブックマークレット】を作成しましたので紹介します。
（アラートで測定IDを表示します）

測定IDの英語表記：Measurement ID

![ga4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/c3eb22a0-9248-d849-9902-92933c4dad50.jpeg)

## 用途
クライアントなど、自身のサイトで無い場合に、GA4にデータ送信しているか？をチェックする際に使います。ソースを見てもわかりますが、サクッと知りたい時にどうぞ。

注意事項：
※GTMでの埋め込まれている場合に機能します。
※gtagが直接ソースに記載されている場合は、
ソースを直接確認すればOKですね。

## コードと使い方

ブックマークレットの使い方：
・下記のコードをコピーする
・適当なブックマークのURLの部分に下記を貼り付ける
・GA4状況をチェックしたいサイトに訪問する
・先ほどのブックマークを押す

```
javascript:mojinum="";kekka="";scp = document.querySelectorAll('script[src*="gtag/js?id=G-"]');for (i = 0; i < scp.length; i++){mojinum=scp[i].src.indexOf('id=G-');kekka = kekka + "\n" + scp[i].src.substr(mojinum+3,12);}if(kekka.length>5){alert(kekka);}else{alert("見つかりません");};
```

## コード解説
クエリセレクター(querySelectorAll）を使い、スクリプトタグの中でもgtag/js?id=Gという文字列が含まれているものを探します。

スクリプトタグは複数ある可能性があるので、forで繰り返します。

※GTM経由で、GA4を導入していると、
gtag/js?id=Gxxxxxxxxという形でJSを読み込んでいますので、
それを確認しているだけです。

## 補足と注意事項
Google側の仕様が変更となった場合は利用できません。
ChromeかつGTM経由のサイトで試していますが、すべて動くとは
保障しきれません。

何卒、ご了承ください。
Laravelのルーティングにおけるnameメソッドについて

# はじめに
下記のように**web.php**内のルーティングの設定時に、**nameメソッド**を使用する用途目的と処理の流れを理解するのためにまとめてみる。

```web.php
Route::get('/test/', 'ArticleController@index')->name('testpage');
```
## 【さきに結論】
ルーティング側でname()メソッドを設定したら、view側でroute()メソッドの引数にname()メソッドと同じ引数を使用できる。

今回welcome.blade.phpのview側のHTMLのリンクタグ`<a href=""></a>` でrouteメソッド利用時に引数にurl名をnameメソッドの引数を当てることができることを確認。

なお、viewのテンプレートへのURLの記述をパス表記でなく、name()メソッドで決めた名前を設定することで、ローティングとビューの設定値が同じため、見やすく確認しやすくなり管理しやすくなる。

## 【利用条件】
Laravel 6
URLのlocalhost:8009がトップページ('/')を表示

## 【確認】
まず、nameメソッドがない場合の動きを確認

```web.php
Route::get('/test/', 'ArticleController@index')
```
URLの/test/にアクセスすると
ArticleControllerクラスの
indexメソッドが処理され実行し、
indexメソッドはindex.blade.phpを表示させる

【関係ファイル】
1.web.php
2.ArticleController.php
3.index.blade.php
4.welcome.blade.php

【処理の流れを確認】
welcom.blade.phpにあるリンク(`<a href=""></a>`)をクリックすると、index.blade.phpのページを表示する処理。

web.phpのURL設定
```web.php
//トップページを表示
Route::get('/', function () {
    return view('welcome');
});
//nameメソッドを追記
Route::get('/test/', 'ArticleController@index')->name('testpage');
```

welcome.blade.phpに下記リンクを追加
```　welcome.blade.php
<a href="{{ route('testpage') }}">testpage</a>
```

-【画面確認】
![スクリーンショット 2022-08-02 21.35.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743849/ec3557c1-23d7-5cda-ac32-522921097d3d.png)

-コントローラーとビューに追記

-【Controller】
```ArticleController.php
class ArticleController extends Controller
{
    public function index(){
        $id = 123;
        return view('index', ['abc' => $id]);
    }
}
```
-【View】
```index.blade.php
<body>
    <p>テストページ</p> 
    {{ $abc }}
</body>
```
-```TESTPAGE```のリンクをクリックし【画面確認】
![スクリーンショット 2022-08-07 17.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743849/f5ddf80e-6d6a-7609-5b5b-c0d59cacffc7.png)


-上記画像のトップデージ```welcome.blade.php```の```testpage```のリンクをクリックしたら、```http://localhost:8009/test```のurlにアクセスできることを確認


## 【参照】
[名前付きルート](https://readouble.com/laravel/6.x/ja/routing.html#:~:text=%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82-,%E5%90%8D%E5%89%8D%E4%BB%98%E3%81%8D%E3%83%AB%E3%83%BC%E3%83%88,-%E5%90%8D%E5%89%8D%E4%BB%98%E3%81%8D%E3%83%AB%E3%83%BC%E3%83%88
)
ブックマークレットの作り方と実装例

化石のようなテクニックで何番煎じかわかららないが、ここ最近でいくつかブックマークレットを作る機会があったので、作り方をまとめておく。今日においても、ブラウザでやるちょっとしたことを自動化するのに便利である。（ブラウザの拡張ツールは要求される権限が広くて心配なことがあるので。）

### ブックマークレットのつくり方

基本的には下記の形式で記述したJavaScriptコードをブックマークのURLとして登録すればよい。コード量が多い場合は[Google Closure Compiler](https://closure-compiler.appspot.com/home)等でminifyをかけるとよい。

```javascript
javascript: (function () { 
    // ここに処理を記述する。
})();
```

表示しているページのDOMにアクセスできるため、そのページでできることはたいてい実現できる。

IDEやエディタで効率よく開発する方法もあるかもしれないが、そこまで複雑なものでなければブラウザの開発者ツールのConsoleでインタラクティブにJavaScriptを実行しながら作る、というスタイルで十分である。

### 実装例

#### Amazonの商品ページURLを簡易化+コピーする

```javascript
javascript: (function () { 
    var e = document.createElement("span");
    e.textContent = "https://amazon.co.jp/dp/" + ue_pti;
    document.body.appendChild(e);

    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.selectAllChildren(e);
    document.execCommand("copy");
    window.location.href = e.textContent;
})();
```

参考：[AmazonのURLを短縮するブックマークレットを作った話 - kick the base](https://www.kickbase.net/entry/amazon-url-shortener)

#### WebページのURLをタイトルにリンクした形式でコピーする

```javascript
javascript: (function () {
    var e = document.createElement('a');
    e.textContent = document.title;
    e.setAttribute('href', document.URL);
    document.body.appendChild(e);

    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.selectAllChildren(e);
    document.execCommand('copy');
    selection.removeAllRanges();
    e.remove();
})();
```
人からもらったiOSアプリがある時から起動、インストールできなくなった

# 結論：プロビジョニングプロファイルが古いのが原因かも
App Storeを通していない自作アプリは、インストールしてから1年以上経つと突然起動しなくなります。
ipaのプロビジョニングプロファイルの有効期限はデフォルトで1年だからです。
同じipaファイルを再作成しない限り、再インストールもできなくなります。

# Unable to install "アプリ名"
ある日を境にして、人からもらったiOSアプリが起動しなくなりました。
とりあえずアプリを一度アンインストールし、再度XCode経由でipaをインストールしようとしたら以下のエラーを吐きます。
![GetImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708163/24da78c1-8608-3d2c-5000-c4141c9bd3de.png)
エラーが何も教えてくれねえ！

コンソールを見て詳細なエラー情報を確認
![GetImage (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708163/3feb52eb-1f1b-a87c-aa83-1fab017eff4c.png)
うーん、やはり何も教える気が無い...

## 試したこと
ちょうどXCodeで作成中のアプリがあったのでそれをインストールしてみたら入る。
インストールに使用した端末は同じなので、違いは「作成者」のみ。
なので恐らくApple独自の認証に関わる問題が発生していると予測。

- 端末に残ったプロビジョニングプロファイルをクリア(ここで気づくべきだった)
- 無課金ユーザはAppStoreを経由しないアプリは3つまでというルールがあるので、アプリをいろいろアンインストール
- iPad、Mac両方の再起動
- 認証情報の再登録

## 原因
前述のとおり、ipaのプロビジョニングプロファイルが古かったです。

# 確認方法
ipaの拡張子をzipに変えて解凍し、中身を確認します。
embedded.mobileprovisionというバイナリファイルがあるので、バイナリエディタで開きます。
この中のExpirationDate/Dateという項目の値が現在時刻よりも前だったら、プロビジョニングプロファイルが古いです。
ipaをビルドし直してプロビジョニングプロファイルを更新しましょう。
canvasアニメーションを使ってみた

canvas要素を使用したアニメーションを使用したことがなかったので、試してみました。
マウスをcanvas上に載せるとアニメーション開始、外すと停止する簡単なアニメーションです。

コードはこちら
[CodePen](https://codepen.io/yaajitaake4/pen/qBoYJeo)

![アニメーション](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663349/1241f8b6-6b02-871b-4cbe-ac1980a25837.gif)


## canvasとは
HTML5から追加され、HTML上に図形(ビットマップ画像)やグラフィックをJavaScriptによって描画できる技術です。
他にも、アニメーション、ゲームのグラフィック、データの可視化、写真加工、リアルタイム動画処理などに使用することができるそうです。
HTMLの<canvas>要素とキャンバスAPIなどを使用して描画します。

## コード

HTMLはcanvas要素、id属性、width属性、height属性を指定しています。
width、heightは描画範囲になりますが、指定しなければ初期値のwidth300px、height150pxが設定されます。

```HTML:HTML
<canvas id="canvas" width="600" height="300"></canvas>
```

CSSは特に指定しなくても問題ないですが、
余白削除とcanvas要素の範囲をわかりやすくするために設定しています。

```CSS:CSS
/* reset */
* {
  margin: 0;
  padding: 0;
}

#canvas {
  background: #eee;
}
```

JSはコメントアウトで説明を記述しています。

```JavaScript:JS
const canvas = document.querySelector('#canvas');
// キャンパスに描画するためのCanvasRenderingContext2Dオブジェクトを取得するメソッド
// 二次元グラフィックを描画するために2dの指定
const ctx = canvas.getContext('2d');
let x = canvas.width / 2;
let y = canvas.height - 30;
let dx = 5;
let dy = 2;
let radius = 20;
let af;

//----- ボールの描画 -----//
function drawBall() {
  // 新しいパスを作成する際の先頭を指定
  ctx.beginPath();
  // arc(円弧の中心の水平座標, 円弧の中心の垂直座標, 円弧の半径, 円弧の開始角度(0°), 円弧の終了角度(360°))
  ctx.arc(x, y, radius, 0, Math.PI * 2);
  // 色の指定
  ctx.fillStyle = "#0095DD";
  // 図形の塗りつぶし
  ctx.fill();
}

//----- ボールの挙動 -----//
function draw() {
  // 図形をクリアする際に使用。図形は切り抜かれて透明に
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBall();
  x += dx;
  y += dy;

  // 衝突検知
  if (y + dy + radius > canvas.height || y + dy - radius < 0) {
    dy = -dy;
  }
  if (x + dx + radius > canvas.width || x + dx - radius < 0) {
    dx = -dx;
  }

  // 繰り返し処理開始
  // ディスプレイのリフレッシュ・レートによって更新速度が変化する
  af = requestAnimationFrame(draw);
}

canvas.addEventListener('mouseover', function (e) {
  // 繰り返し処理開始
  af = requestAnimationFrame(draw);
});

canvas.addEventListener('mouseout', function (e) {
  // 繰り返し処理の停止
  cancelAnimationFrame(af);
});

drawBall();
```

## おまけ
上記の2Dアニメーションだとcanvasタグを使用しなくても実装できそうですが、今後3Dアニメーションを行う上でcanvasAPIの動作を知るにはちょうど良いのではないかと思いました。
簡単ですが、canvasAPIとライブラリを使用してテキストのアニメーションを試してみました。



コードはこちら
[Codepen](https://codepen.io/yaajitaake4/pen/PoRexMG)




最近は３Dアニメーションのためのライブラリが充実しており、リッチなWEBサイトが非常に多くなってきています。
そんなWEBサイトを作ってみたいですし、WEBグラフィックを作れたらかっこいいですよね。

## 参考サイト
https://vincentgarreau.com/particles.js/
https://balance.bz/magazine/webgr2022/
https://dribbble.com/tags/particle_js
https://developer.mozilla.org/ja/docs/Web/HTML/Element/canvas
STM32L010とDS1307で時間合わせ


x Mbed2リビジョン125です。

目的
RTCの時間合わせ
タイミングよく実行する


ちゃんと原文を確認してね!!

x 非営利、研究調査目的で引用


![o_con625.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/20a36287-8ee2-9707-191d-90c061415426.jpeg)



```c++


//i2c_oled16x24_64_ds1307_set_010_1

#include "mbed.h"

#define HH  17
#define MM  28

int main() {
    char data_read[8];  //i2cバッファー
    data_read[0]=0;
    data_read[1]=0;
    data_read[2]= ( MM /10)*16+( MM %10);
    data_read[3]= ( HH /10)*16+( HH %10);
    data_read[4]=3;    
    data_read[5]=1;
    data_read[6]=1;
    data_read[7]=0x20;

    I2C i2c(PA_10, PA_9);
    i2c.write(  (0xD0)  , data_read, 8);

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



```
プロキシ経由のAmazon ECR Public Gallery利用時の注意

[Amazon ECR Public Gallery](https://gallery.ecr.aws/)を利用する際の注意点について記載します。

1. ECR PublicのVPCエンドポイントが提供されていないので、dockerコマンド(例:pull)実行時にCloudFront への通信が発生する
1. [CloudFrontの接続先が明記されていない](https://aws.amazon.com/jp/blogs/aws/amazon-ecr-public-a-new-public-container-registry/)ので、実際にpull等してみて接続先ドメインを特定して、プロキシのホワイトリストに追加する
1. 以下のDockerfileを用意した場合の接続先は、`d5l0dvt14r5h8.cloudfront.net`となった

```Dockerfile
FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:2.26.0
```
※ `FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:2.19.0`のときには異なるcloudfrontのドメインだったので、タイミングなのか、コンテナイメージのバージョンなのかわかりませんが実際にpullしてみて確認が必要
知っていて当たり前-12　集合

# 知っていて当たり前-12　集合

## 1.　集合を定義する方法 `Set()`


```julia
s = Set([2,1,2,1,1,3,4,2,1])
```




    Set{Int64} with 4 elements:
      4
      2
      3
      1



単純に `sort()` では並べ替えできない。


```julia
sort(s)　# エラーになる
```


    MethodError: no method matching sort(::Set{Int64})
    Closest candidates are:
      sort(::AbstractUnitRange) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/range.jl:1304
      sort(::AbstractRange) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/range.jl:1307
      sort(::SparseArrays.SparseVector{Tv, Ti}; kws...) where {Tv, Ti} at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/SparseArrays/src/sparsevector.jl:1968
      ...

    

    Stacktrace:

     [1] top-level scope

       @ In[2]:1

     [2] eval

       @ ./boot.jl:373 [inlined]

     [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)

       @ Base ./loading.jl:1196


並べ替えを行うには，以下のようにする。


```julia
sort([i for i in s])
```




    4-element Vector{Int64}:
     1
     2
     3
     4




```julia
s1 = Set([1, 2, 1, 2, 3, 4, 3, 2, 5])
s1
```




    Set{Int64} with 5 elements:
      5
      4
      2
      3
      1




```julia
values(s1)
```




    Set{Int64} with 5 elements:
      5
      4
      2
      3
      1



## 2.　要素の取り出し


```julia
a = [i for i in s]
```




    4-element Vector{Int64}:
     4
     2
     3
     1



## 3.　空集合


```julia
a = Set()
```




    Set{Any}()



## 4.　要素の追加 `push!()`

順に追加されるわけではない。


```julia
push!(a, "a")
push!(a, 2, 3.5)
a
```




    Set{Any} with 3 elements:
      2
      3.5
      "a"



## 5.　要素に含まれるかどうかの判定


```julia
in("b", a)
```




    false




```julia
in(3.5, a)
```




    true



## 6.　要素の取り出し `pop!()`


```julia
pop!(a, "a")
a
```




    Set{Any} with 2 elements:
      2
      3.5



## 7.　和集合 `union()`, `union!()`


```julia
a = Set([1,3,5,7,9])
b = Set([1,2,3,4])
union(a, b)
```




    Set{Int64} with 7 elements:
      5
      4
      7
      2
      9
      3
      1



## 8.　積集合 `intersect()`, `intersect!()`


```julia
intersect(a, b)
```




    Set{Int64} with 2 elements:
      3
      1



## 9.　差集合（a から b にある要素を除く） `setdiff()`, `setdiff!()`


```julia
setdiff(a, b)
```




    Set{Int64} with 3 elements:
      5
      7
      9




```julia
setdiff(b, a)
```




    Set{Int64} with 2 elements:
      4
      2



## 10.　和集合から積集合を除く `symdiff()`, `symdiff!()`


```julia
symdiff(a, b)
```




    Set{Int64} with 5 elements:
      5
      4
      7
      2
      9



## 11.　包含 `issubset()`


```julia
issubset(a, b)
```




    false



## 12.　同一か? `issubset()`


```julia
issubset(a, b)
```




    false



## 13.　空集合か？


```julia
isempty(a)
```




    false



## 14.　要素数 `length()`


```julia
length(a)
```




    5



## 15.　空集合にする `empty!()`


```julia
empty!(a)
```




    Set{Int64}()




```julia
isempty(a)
```




    true
世界一優しいReactの基本その2 -コンポーネントとは-

## はじめに
前回はReactの基本を学びました。今回はコンポーネントとはなにか？というところを書いていきたいと思います。

https://qiita.com/k-tetsuhiro/items/c829e7d5a5e7000f1cad


## Reactの環境を作る
前回同様、CodeSandboxにてサクッと環境を作ってみます。詳しくは前回の記事を見てみてください。

https://codesandbox.io/

開発環境が立ち上がると下記のようなファイルと、ブラウザに文字が表示されています。

![Screen Shot 2022-08-07 at 16.31.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174291/014588b0-2968-e7a9-8c40-bebfb4c7ceef.png)


## コンポーネントとは
コンポーネントとは部品のことです。前回の記事でApp.jsでコンポーネントという単語が出てきましたが、今回はもう少し細かくコンポーネントを分けていきます。

index.jsを見てみると既にApp.jsというコンポーネントをimportして利用していることがわかります。
この`<App />`タグのところがAppコンポーネントで書かれているhtmlが表示される仕組みになっています。

```index.js
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

// Appコンポーネントをimportしている
import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    {/* Appコンポーネントを表示している */}
    <App />
  </StrictMode>
);
```

では次に、App.jsコンポーネントの中ではシンプルにブラウザに表示しているhtmlが記載されています。
この中身は非常にシンプルなのでわかりやすいと思います。

```App.js
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

```

## コンポーネントを作ってみる
実際にコンポーネントを作ってApp.jsでそれを利用してみたいと思います。

### コンポーネントファイルの拡張子
Reactでは基本的にJavaScriptが動くのでファイルの拡張子は.jsで動作するのですが、コンポーネント用の`.jsx`という拡張子が用意されています。試しにApp.jsをApp.jsxに変更しても変わらず動くはずです。
![Screen Shot 2022-08-07 at 17.11.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174291/7b1efcc2-8780-70e8-9294-ad2b53558207.png)

### コンポーネントを新規に作る
では実際にコンポーネントを作ってみましょう。コンポーネントファイルは`componentsフォルダ`に作成する習慣があるのでcomponentsフォルダを新規に作成して、その下に`Button.jsx`ファイルを作ります。
![Screen Shot 2022-08-07 at 17.14.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174291/e6870321-74be-c1d3-3638-d4e9d0baaba5.png)

Button.jsxファイルではボタンを２つ表示するだけのシンプルなhtmlを返したいと思います。
ここで重要なのは`export`しているというところです。**exportすることで他のファイルでもimportして利用する事ができます。**

```Button.jsx
export const Button = () => {
  return (
    <div>
      <button>ボタン１</button>
      <button>ボタン２</button>
    </div>
  );
};
```

これをApp.jsで利用したいので、App.jsでButtonコンポーネントをimportして表示してみます。
するとブラウザButtonコンポーネントが表示されボタンが2個表示されているのが確認できます。

```App.js
import "./styles.css";
// Buttonコンポーネントをインポート
import { Button } from "./components/Button";

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {/* Buttonコンポーネントを表示 */}
      <Button />
    </div>
  );
}
```

![Screen Shot 2022-08-07 at 17.20.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174291/974a910e-6a4b-59de-fffc-45d0bb9fead2.png)


## まとめ
コンポーネントをうまく利用すると、まさに部品のように利用するhtmlを細かくわける事ができます。
これにより、再利用することが可能になりメンテナンス性が非常にあがります。
次回はPropsやStateなどの少し難しい概念を学んでいきます。
datepickerについてまとめる ~楽にカレンダーコントロールを実装~

#### はじめに
カレンダーコントロールについて色々調べた結果、datepickerに行き着いたので記事にしようと思いました。
FullCalendar.jsも無料版で色々やれそうで面白かったので、また別の記事でまとめていこうと思います。

#### datepickerって何？
jquery UIのライブラリに含まれるカレンダー表示機能。

![qiita0807.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1928016/8c64a9c4-e50e-97c5-ed1b-983ee9b1ea4a.png)

こんな感じのカレンダーを低いコストで実装できる。

#### datepickerの実装方法
jquery UIはCDNで実装できる。

```HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.min.css"> 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js"></script>
```

**この2行をソースコードに追加するだけでdatepickerを実装できる。
後はdatepickerメソッドを呼び出すだけ。**

```HTML

<h3>date pickerを試す</h3>
<input type="text" id="currender_1">

<script>
$('#currender_1').datepicker();
</script>
```

この状態だと、datepickerには初期値が設定されていない。
datepickerには色々なメソッドが用意されており、初期値の設定にはsetDateを使う。

```HTML
<script>
  const datetime = new Date();
  const datetime_today = datetime.getFullYear() + "-" +
                        (datetime.getMonth() + 1)  + "-" + 
                         datetime.getDate(); 
  $('#currender_1').datepicker({dateFormat: 'yy-mm-dd'});
  $("#currender_1").datepicker("setDate", datetime_today);
</script>
```
これで最初から値を入れることができる。


一応、コードの意図を説明すると
new Date()でJavascriptのDateオブジェクトを生成している。
datetime.getMonth() + 1 の意図は値の開始地点が0～なので、1を足して実際の月と合わせている。

#### datepickerの日本語化
日本語化もCDNで対応できる（便利）。

```HTML
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js"></script>
```
先程、記述したCDN読み込み時のソースコードに上記を付け足すだけで日本語化できる。

#### datepickerのデザイン変更

datepickerには様々なデザインが用意されており、デザインを変更するにはCDN読み込み時のコードを変えるだけ。
その一例を示すと、

```HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.min.css"> 
```

上記のコードのbaseの部分をstartに変更するだけ。

```HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/start/jquery-ui.min.css"> 
```


![qiita0807-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1928016/08fc7624-ba32-57a5-f4fb-6d5129a120b2.png)

これだけで表示されるカレンダーのデザインが変わる。


#### 最後に
**実装のハードルの低さを鑑みると、簡易的なカレンダーコントロールの実装にはdatepickerがお勧めなのかなと感じました。**
オプションも豊富で選択できる期間の制限もかけることが出来たりします。

ただ、カレンダーにスケジュールなどのイベントを追加するってなると、FullCalendar.jsや自作で作った方がいいのではと感じました。