高木のブログ

【Elixir】テストを書いてみる

Tags: Elixir

Elixir でのテストを触りだけやる

バージョン 🔗

$ elixir -v
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]

Elixir 1.14.2 (compiled with Erlang/OTP 25)

$ mix -v
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]

Mix 1.14.2 (compiled with Erlang/OTP 25)

プロジェクト作成 🔗

mix new でプロジェクトを作成する

$ mix new hello

以下のファイル群が生成された

$ cd hello
$ tree .
.
├── README.md
├── lib
│   └── hello.ex
├── mix.exs
└── test
    ├── hello_test.exs
    └── test_helper.exs

2 directories, 5 files

hello.ex には、:world を返す hello 関数が定義されている

$ iex -S mix
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]

Interactive Elixir (1.14.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Hello.hello
:world

mix test でテストを実行する

Elixir で Hello, World!

Tags: Elixir

Elixir も触っておきたいなと思ったので、取り急ぎの Hello, World! をやってみた

インストール 🔗

Mac は HomeBrew でインストールすることができる

$ brew install elixir
$ elixir --version
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]

Elixir 1.14.2 (compiled with Erlang/OTP 25)

他のインストール方法は https://elixir-lang.org/install.html を参照

インタラクティブモード 🔗

いわゆる REPL

$ iex
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]

Interactive Elixir (1.14.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 1 + 2
3

Ctrl + C を2回で終了できる

スクリプトモードで Hello, World! 🔗

拡張子 exs でファイルを作って、elixir ファイル名 で実行

defmodule Hello do
  def greet do
    IO.puts "Hello, World!"
  end
end
$ elixir hello.exs
Hello, World!

コンパイルして Hello, World! 🔗

拡張子 ex でファイルを作って、elixirc ファイル名 でコンパイル

Heroku の PostgreSQL のデータをバックアップしてローカルのデータベースにリストアする

pg_dump と pg_restore を使ったやり方なので、Heroku 関係なしにできる

Heroku のPostgreSQL からバックアップ 🔗

$ PGPASSWORD=${パスワード} pg_dump --format=custom --no-acl --no-owner -h ${ホスト名} -U ${ユーザー名} ${データベース名} > app_production.custom

フォーマットはカスタム形式にしている

データベース情報の確認 🔗

Heroku で使っている PostgreSQL の情報は以下のコマンドで確認することができる

$ heroku pg:credentials:url

ローカルにリストア 🔗

$ pg_restore --clean --no-acl --no-owner -h ${ホスト名} -U ${ユーザー名} -d ${データベース名} app_production.custom

Heroku のデータベースとローカルのデータベースの違いが原因で警告が表示されるが、無視しても問題ないらしい
実際にリストアできていることが確認できた

参考 🔗

Next.js 13 に NextUI を導入する

Tags: Next.js NextUI

Next.js 13 の app ディレクトリモード?に NextUI を導入した時のメモ

NextUI はまだ Next.js 13 に完全対応はしておらず、とりあえず動くところまで持っていけただけなので参考程度に

前提条件 🔗

以下コマンドで Next.js のアプリを作成したばかりところに導入する

$ yarn create next-app app_name --typescript --experimental-app

手順 🔗

インストール 🔗

$ yarn add @nextui-org/react

セットアップ 🔗

app/providers.tsx を作成

"use client"

import { useServerInsertedHTML } from "next/navigation"
import { NextUIProvider, CssBaseline } from "@nextui-org/react"

export function Providers({ children }: { children: React.ReactNode }) {
  useServerInsertedHTML(() => {
    return <>{CssBaseline.flush()}</>
  })

  return <NextUIProvider>{children}</NextUIProvider>
}

app/layout.tsx を以下のように修正

 import "./globals.css"
+import { Providers } from "./providers"

 export default function RootLayout({
   children,
 }: {
   children: React.ReactNode
 }) {
   return (
     <html lang="en">
       <head>
         <title>Create Next App</title>
         <meta name="description" content="Generated by create next app" />
         <link rel="icon" href="/favicon.ico" />
       </head>
-      <body>{children}</body>
+      <body>
+        <Providers>{children}</Providers>
+      </body>
     </html>
   )
 }

動作確認 🔗

ボタンを仮設置して、NextUI が有効になっているかを確認する

【GitHub Actions】Raspberry Pi でセルフホストランナーを起動する

GitHub Actions の セルフホストランナーを Raspberry Pi で起動してみた
基本は公式ドキュメントと設定画面に表示される手順でサクッとできる

ランナーはリポジトリ単位かオーガニゼーション単位で起動できる
ユーザー単位ではできないっぽい

今回はリポジトリに対してランナーを起動
悪意のあるコードが実行される可能性があるのでリポジトリはプライベートで作成することが推奨されている

環境 🔗

  • Raspberry Pi 4 Model B
  • Raspberry Pi OS 10.11

手順 🔗

リポジトリの「Settings」->「Actions」->「Runners」->「New self-hosted runner」からランナーを追加できる

Runner image は Linux、Architecture は ARM を選択

環境に合った手順が表示されるのでそれをただ実行するだけ

ダウンロード 🔗

$ mkdir actions-runner && cd actions-runner
$ curl -o actions-runner-linux-arm-2.299.1.tar.gz -L https://github.com/actions/runner/releases/download/v2.299.1/actions-runner-linux-arm-2.299.1.tar.gz
$ tar xzf ./actions-runner-linux-arm-2.299.1.tar.gz

設定 🔗

./config.sh --url https://github.com/ユーザー名/リポジトリ名 --token トークン

対話形式でいろいろ聞かれるが、基本そのままエンターキーで良い

起動 🔗

$ ./run.sh

√ Connected to GitHub

Current runner version: '2.299.1'
2022-11-16 11:25:51Z: Listening for Jobs

ランナーが追加され、Status が 「Idle」になっていることが確認できた

【GitHub Actions】「Node.js 12 actions are deprecated.」の対応

とある Ruby のプロジェクトの GitHub Actions のページを開いたら、以下の警告が出ていた

Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: actions/checkout, actions/checkout

GitHub Actions で Node.js 12 のサポートが終了するから Node.js 16 に切り替えろとのこと
Ruby のプロジェクトだけど、actions/checkout で Node.js を使っているため対応する必要がある

対応方法 🔗

actions/checkout@v2 から actions/checkout@v3 に変更するだけで良い

     name: Ruby ${{ matrix.ruby }}
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
     - name: Set up Ruby
       uses: ruby/setup-ruby@v1

Dependabot で GitHub Actions のアクションを自動更新する 🔗

手動で対応するのは面倒なので、ライブラリなどと同じようにアクションも Dependabot で更新するようにした

【Vagrant】CPU の数を変更する

Tags: Vagrant

仮想マシンに割り当てる CPU の数を増やしたかった
メモリを増やす方法と同じやり方でできた

config.vm.provider "virtualbox" do |vb|
  # Display the VirtualBox GUI when booting the machine
  # vb.gui = true

  # Customize the amount of memory on the VM:
  vb.memory = "15360"

+ vb.cpus = "3"
end
$ grep processor /proc/cpuinfo | wc -l
3

CPU のコア数が3になっていることが確認できる

参考 🔗

Vagrant で VirtualBox 仮想マシンの CPU 数とメモリサイズを変更 - なんとなくな Developer のメモ 物理 CPU、CPU コア、および論理 CPU の数を確認する - Red Hat Customer Portal

git diff コマンドで省略せず全行表示する

git diff はデフォルトで変更された行の前後3行分だけ表示されるようになっている

$ git diff main.tf
diff --git a/main.tf b/main.tf
index e82334f..361f6ac 100644
--- a/main.tf
+++ b/main.tf
@@ -1,3 +1,7 @@
+variable access_key {}
+variable secret_key {}
+variable endpoints_s3 {}
+
 terraform {
   required_providers {
     aws = {
@@ -8,13 +12,13 @@ terraform {
 }

 provider "aws" {
-  access_key = "access key"
-  secret_key = "secret key"
+  access_key = var.access_key
+  secret_key = var.secret_key
   skip_credentials_validation = true
   skip_region_validation = true
   skip_requesting_account_id = true
   endpoints {
-    s3 = "https://<account id>.r2.cloudflarestorage.com"
+    s3 = var.endpoints_s3
   }
   region = "auto"
 }

省略しないで全て表示させたい時は、-U<任意の数字> オプションを使うと良い
変更された行の前後<任意の数字>分表示されるようになる

【Faraday】HTTP/2 でリクエストする

HTTP/2 でしか何故か受け付けない API があったので調べた

手順 🔗

Typhoeus の Faraday 用のミドルウェア(アダプター)、faraday-typhoeus を使う

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'faraday'
  gem 'faraday-typhoeus'
end

conn = Faraday.new(url: 'https://example.com') do |conn|
  conn.adapter :typhoeus, http_version: :httpv2_0
end

puts conn.get('/').body

動作確認 🔗

これで実際に HTTP/2 でリクエストできているのかを確認する
確認方法には nc コマンドを使った

$ ( echo "HTTP/1.1 200 OK"; echo; echo "Hello World" ) | nc -l 5555

HTTP/1.1 🔗

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'faraday'
end

conn = Faraday.new(url: 'http://localhost:5555')

puts conn.get('/').body
$ ruby faraday-http2.rb
Hello World
$ ( echo "HTTP/1.1 200 OK"; echo; echo "Hello World" ) | nc -l 5555
GET / HTTP/1.1
User-Agent: Faraday v2.6.0
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
Host: localhost:5555

シンプルに Faraday を使うと HTTP/1.1 になっている

switchbot gem v0.7.0 をリリースした

SwitchBot API 用の Gem、switchbot v0.7.0 をリリースした
このリリースで、SwitchBot API v1.1 を使うようになった

https://rubygems.org/gems/switchbot
ytkg/switchbot - GitHub

変更点 🔗

認証方法の変更 🔗

SwitchBot API v1.1 では認証方法が変わり、トークンに加えてシークレットも必要になった
シークレットはトークンと同じく SwitchBot のアプリから取得できる

client = Switchbot::Client.new('YOUR_TOKEN', 'YOUR_SECRET')

SwitchBot ロックに対応 🔗

認証方式が変わってセキュリティが強化されたので、API 経由でロックの解錠・施錠ができるようになった

client = Switchbot::Client.new('YOUR_TOKEN', 'YOUR_SECRET')

client.lock('C271111EC0AB').unlock
#=>
#{:status_code=>100,
# :body=>
#  {:items=>
#    [{:device_id=>"C271111EC0AB",
#      :code=>100,
#      :status=>
#       {:door_state=>"closed",
#        :is_slave=>false,
#        :door_state_source=>"master",
#        :is_slave_online=>false,
#        :battery=>95,
#        :pause_auto_lock=>false,
#        :lock_state=>"unlocked",
#        :last_action_source=>"autoLock",
#        :is_calibrate=>true,
#        :power=>"on",
#        :is_group=>false,
#        :door_opened_overtime_warning=>false,
#        :unlocked_overtime_warning=>false},
#      :message=>"success!"}]},
# :message=>"success"}

client.lock('C271111EC0AB').lock
#=>
#{:status_code=>100,
# :body=>
#  {:items=>
#    [{:device_id=>"C271111EC0AB",
#      :code=>100,
#      :status=>
#       {:door_state=>"closed",
#        :is_slave=>false,
#        :door_state_source=>"master",
#        :is_slave_online=>false,
#        :battery=>95,
#        :pause_auto_lock=>false,
#        :lock_state=>"locked",
#        :last_action_source=>"command",
#        :is_calibrate=>true,
#        :power=>"on",
#        :is_group=>false,
#        :door_opened_overtime_warning=>false,
#        :unlocked_overtime_warning=>false},
#      :message=>"success!"}]},
# :message=>"success"}

AWS CLI で S3 からワイルドカードで指定してファイルをダウンロードしたい

S3 に yyyy-mm-dd.csv という名前の形式で CSV ファイルが保存されている

$ aws s3 ls s3://path/to/
2017-01-20 18:03:55      47968 2014-10-16.csv
2017-01-20 18:02:47      71855 2014-10-17.csv
2017-01-20 18:02:45      73806 2014-10-18.csv
...
2022-10-24 03:21:43    7162892 2022-10-21.csv
2022-10-24 03:21:40    6656291 2022-10-22.csv
2022-10-24 03:21:39    5379009 2022-10-23.csv

不具合の調査で4月分の CSV ファイルをダウンロードしたかった

$ aws s3 ls s3://path/to/2022-04
2022-04-04 03:19:20    8364026 2022-04-01.csv
2022-04-05 03:20:20    8394353 2022-04-02.csv
2022-04-06 03:18:53    8243473 2022-04-03.csv
...
2022-05-01 03:18:09    8029591 2022-04-28.csv
2022-05-02 03:18:00    7992829 2022-04-29.csv
2022-05-03 03:18:49    7502806 2022-04-30.csv

ls コマンドで絞り込みできるなら cp コマンドでもできるだろうと思ったらできなかった

$ aws s3 cp s3://path/to/2022-04 .
fatal error: An error occurred (404) when calling the HeadObject operation: Key "path/to/2022-04" does not exist

–recursive オプションと –exclude オプション と –include オプションを使うと絞り込みができた

HomeBrew で最新版の q をインストールする

Tags: q HomeBrew

HomeBrew で q をインストールしようとしたら、brew install q では最新版が入らなかった

$ brew install q
$ q -v
q version 2.0.20
Python: 3.9.15 (main, Oct 11 2022, 22:26:39) // [Clang 13.0.0 (clang-1300.0.29.30)]
Copyright (C) 2012-2020 Harel Ben-Attia ([email protected], @harelba on twitter)
http://harelba.github.io/q/

正しいインストール方法 🔗

どうやら公式のフォーミュラから削除したっぽい

$ brew install harelba/q/q
$ q -v
q version 3.1.6
Python: 3.9.7 (default, Oct 18 2021, 00:59:13) // [Clang 13.0.0 ]
Copyright (C) 2012-2021 Harel Ben-Attia ([email protected], @harelba on twitter)
http://harelba.github.io/q/

【Ruby】Base64.encode64 は改行コードが入る

Tags: Ruby

Ruby で Base64.encode64 を使った時に末尾に改行コード(\n)が入っていることに気がついた

require 'base64'

Base64.encode64('こんにちはこんにちはこんにちはこんにちは')
#=> "44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv\n44GT44KT44Gr44Gh44Gv\n"

RFC2045 の仕様に準拠していて、末尾以外にも60文字ごとに改行コードが追加されるっぽい(Base64.#encode64 (Ruby 3.1 リファレンスマニュアル)

改行コードが入って欲しくない時は、Base64.strict_encode64 を使うと良い

require 'base64'

Base64.strict_encode64('こんにちはこんにちはこんにちはこんにちは')
#=> "44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv"

これは RFC4648 の仕様に準拠している(Base64.#strict_encode64 (Ruby 3.1 リファレンスマニュアル)

参考 🔗

RubyのBase64.encode64はエンコード後文字列が60文字以上になると改行コードが入る - コード日進月歩

SwitchBot API v1.1 の認証(Ruby バージョン)

先日、SwitchBot API の v1.1 が公開された
v1.1 では認証方法が変わっている
公式ドキュメント には Python と JavaScript での認証方法のサンプルコードが載っていたが、Ruby がなかったので書いてみた

コード 🔗

require 'securerandom'
require 'base64'
require 'openssl'

token = 'hoge-token'
secret = 'fuga-secret'
t = (Time.now.to_f * 1000).to_i
nonce = SecureRandom.alphanumeric

sign = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', secret, "#{token}#{t}#{nonce}"))

puts "Authorization: #{token}"
puts "t: #{t}"
puts "sign: #{sign}"
puts "nonce: #{nonce}"
  • token: アクセストークン
  • secret: アクセストークンシークレット(SwitchBot アプリ v6.14 以降で取得可能)
  • t: 13桁のタイムスタンプ
  • nonce: 利用するプログラムで生成した UUID キー
  • sign: 特定のアルゴリズムで生成した文字列

実行 🔗

実行すると必要な情報が出力される

$ ruby app.rb
Authorization: hoge-token
t: 1665582731060
sign: Lk4PPsJLZXAN6yhRTfhE5Vargx9N0iIBJRO+YeAkyJU=
nonce: flMkSCm3PkBgOukF

リクエストヘッダーに追加して curl などでリクエストしたらOK(例はデバイスを取得する)

$ curl -X GET 'https://api.switch-bot.com/v1.1/devices' \
--header 'Authorization: hoge-token' \
--header 't: 1665582731060' \
--header 'sign: Lk4PPsJLZXAN6yhRTfhE5Vargx9N0iIBJRO+YeAkyJU=' \
--header 'nonce: flMkSCm3PkBgOukF'

本当は Ruby で API を叩くところまでやりたかったけど、なぜかうまくいかなかったので調査中

Terraform で Cloudflare R2 のバケットを作成する

Terraform の肩慣らしとして、Cloudflare R2 のバケットを作成してみた

Cloudflare R2 のドキュメントに書いてあったものを参考にした
https://developers.cloudflare.com/r2/examples/terraform/

Terraform バージョン 🔗

$ terraform -v
Terraform v1.3.2
on darwin_amd64

手順 🔗

設定ファイルを作成 🔗

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "4.34.0"
    }
  }
}

provider "aws" {
  access_key = "access key"
  secret_key = "secret key"
  skip_credentials_validation = true
  skip_region_validation = true
  skip_requesting_account_id = true
  endpoints {
    s3 = "https://<account id>.r2.cloudflarestorage.com"
  }
  region = "auto"
}

resource "aws_s3_bucket" "cloudflare-bucket" {
  bucket = "my-tf-test-bucket"
}

access key と secret key は R2 の管理画面、「R2 API トークンの管理」から作成できる
編集の権限を付けて作成した

OSS のコントリビュート状況を確認する

Tags: OSS GitHub

自分が今までどのくらい OSS にコントリビュートしてきたか確認したかった

https://github.com/pulls で「involves:{username} -user:{username}」を検索したら確認できる

検索オプションについて 🔗

involves 🔗

関連している人(Issue or PR を作成した人、アサインされている人、コメントしている人、メンションが飛んでいる人)の絞り込み

個別に

  • author: Issue or PR を作成した人
  • assignee: アサインされている人
  • commenter: コメントしている人
  • mentions: メンションが飛んでいる人 で指定できる

user 🔗

リポジトリのオーナーの絞り込み

自分のリポジトリは不要なので、- を付けて(-user)で除外している

所属しているオーガニゼーションも除外したかったら、-org を使う

例 兼 自分用リンク 🔗

https://github.com/pulls?q=involves%3Aytkg+-user%3Aytkg

実際には、身内のリポジトリと会社のオーガニゼーションを除外して確認している

参考 🔗

【Deno】deno init コマンド

Tags: Deno

Deno 1.25.0 で、プロジェクトの初期化をしてくれるサブコマンド deno init が追加された

$ deno --version
deno 1.25.4 (release, x86_64-apple-darwin)
v8 10.7.193.3
typescript 4.7.4

コマンドを実行すると、main.tsmain_test.ts の2つのファイルが生成される

$ deno init
✅ Project initialized
Run these commands to get started
  deno run main.ts
  deno test
$ ls
main.ts      main_test.ts

Deno の基本的な書き方とそのテストの例が書かれている

export function add(a: number, b: number): number {
  return a + b;
}

// Learn more at https://deno.land/manual/examples/module_metadata#concepts
if (import.meta.main) {
  console.log("Add 2 + 3 =", add(2, 3));
}
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
import { add } from "./main.ts";

Deno.test(function addTest() {
  assertEquals(add(2, 3), 5);
});
$ deno run main.ts
Add 2 + 3 = 5
$ deno test
running 1 test from ./main_test.ts
addTest ... ok (7ms)

ok | 1 passed | 0 failed (41ms)

Deno はたまにしか書かず、久々に書こうとした時にどうやって書くんだっけと毎回ググったり、他リポジトリを覗きにいったりしていたのでこのコマンドの追加は嬉しい
もちろん複雑なプログラムを書く時は他のことでどうせググるだろうけど、取っ掛かりまでのハードルが大幅に下がったのは大きい

tfenv で Terraform をインストールする

Tags: Terraform

Terraform を使う機会が出てきたので tfenv でインストールした

tfenv のインストール 🔗

tfenv 自体は Homebrew でインストール

$ brew install tfenv
$ tfenv -v
tfenv 3.0.0

Terraform のインストール 🔗

$ tfenv install
$ tfenv use 1.3.0
$ terraform -v
Terraform v1.3.0
on darwin_amd64

引数にバージョンを指定しないと、環境変数 TFENV_TERRAFORM_VERSION で指定されたバージョンか、.terraform-version で指定されたバージョンか、latest がインストールされるっぽい(優先順位は記述順)

他、よく使いそうなコマンド 🔗

インストール済みのバージョンを確認 🔗

$ tfenv list
* 1.3.0 (set by /usr/local/Cellar/tfenv/3.0.0/version)

インストール可能なバージョンを確認 🔗

$ tfenv list-remote
1.3.0
1.3.0-rc1
1.3.0-beta1
1.3.0-alpha20220817
1.3.0-alpha20220803
1.3.0-alpha20220706
1.3.0-alpha20220622
1.3.0-alpha20220608
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0

省略したけど、全部のバージョンが表示された
長いので rbenv とかみたいにデフォルトは安定板のみ表示して欲しいと思った

【Sinatra / Rails】ユーザーID に ULID を使うことにした

Tags: Sinatra Rails

Rails でも同じなのでタイトルに追加している

Sinatra アプリでユーザーの ID に UUID を使っていたが、ULID に切り替えた

ULID は、UUID と互換性があり、ミリ秒単位で時系列ソートができる

Gem があったのでそれを使うことにした
https://github.com/rafaelsales/ulid

require 'ulid'

ULID.generate
#=> "01G9VYHMNH5YWA0B96K1Q1KBHB"

以前書いた記事(【Rails / Sinatra】ID を UUID にする ) のモデルを以下のように書き換えるだけで移行完了

require 'ulid'

class User < ActiveRecord::Base
  before_create -> { self.id = ULID.generate }
end

【Discord】Webhook でメッセージを送信する

Tags: Discord

Wenhook URL は、「サーバー設定」->「連携サービス」->「ウェブフックを確認」->「新しいウェブフック」で作成できる

$ curl -X POST -H 'Content-Type: application/json' https://discord.com/api/webhooks/1234565/HOGEHOGE -d '{"content": "Hello!"}'

参考 🔗

Discord に Webhook でいろいろ投稿する - Qiita https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks

Cookpad Code Puzzle for RubyKaigi 2022 をやった

Tags: Ruby RubyKaigi

Cookpad Code Puzzle for RubyKaigi 2022

func4 から急に難しくなったけど、なんとか func10 まで解けた

001.png

func10 は変に難しく考えてしまい、無駄に時間掛かってしまった
素直に同じ挙動をするメソッドを書けばいい

func11 以降の解き方 🔗

func20 まであるらしいけど、func11 から問題が出てこない

以下のように自分で定義して実行したらいいっぽい

p func11

def answer11
end

ちなみに実行例やヒントはない

参考 🔗

Yusuke EndohさんはTwitterを使っています: #rubykaigi のクックパッドのブース企画だったRubyパズル、今週金曜日ごろに解説記事を書こうと思います。自力で解きたい人はそれまでにどうぞ。https://ruby-puzzles-2022.cookpad.tech スレッドに各問題のヒントを付けておきますね。

【Ruby】タイムゾーンを変更する

Tags: Ruby

GitHub Actions で時間を扱うRuby スクリプトを動かしたい
そのためには、GitHub Actions のタイムゾーンは UTC になっているので、タイムゾーンを変更する必要がある

Ruby はシステムのタイムゾーンに依存する 🔗

puts Time.now
$ ruby app.rb
2022-09-10 20:14:08 +0900

環境変数 TZ を指定してタイムゾーンを変更する 🔗

システムのタイムゾーンを変更するか、環境変数 TZ で指定してあげれば変更できる
環境変数で指定するのが手軽そう

$ TZ=UTC ruby app.rb
2022-09-10 11:14:33 +0000
$ TZ=America/New_York ruby app.rb
2022-09-10 07:14:46 -0400

GitHub Actions で日本時間で Ruby スクリプトを実行する 🔗

GitHub Actions では、上記の実行時に TZ を指定するやり方と、env で TZ を指定するやり方ができる

実行時に TZ を指定 🔗

jobs:
  ruby:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: 3.1
    - name: Run script
      run: TZ=Asia/Tokyo ruby app.rb

env で TZ を指定 🔗

jobs:
  ruby:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: 3.1
    - name: Run script
      env:
        TZ: "Asia/Tokyo"
      run: ruby app.rb

参考 🔗

#Ruby と #Rails の Time や Time.zone の扱いががマジで分からないし混沌としてるのでちょっとだけ整理したい。 - Qiita

【Mac】date コマンドで UNIX 時間を通常時間に変換する

「dateコマンド unixtime 変換」とかでググって出てくるやり方ではうまくいかなくて詰まった

$ date -r 1662471704
2022年 9月 6日 火曜日 22時41分44秒 JST

補足 🔗

  • GNU 系とBSD 系で date コマンド が微妙に違う(Mac は BSD 系)

以下は GNU 系のやり方

$ date -d @1583900131
2022年 9月 6日 火曜日 22:41:44 JST
  • UNIX 時間 == エポック秒 == POSIX 時間

参考 🔗

unixtimeとdatetimeを変換する(Mac/BSD編) - Qiita

【JavaScript】Fetch API で Basic 認証

Tags: JavaScript

Basic 認証が掛かった API からデータを取得するコードを書くことがよくある
その度に調べているのでメモ

#!/usr/bin/env zx

const username = "takagi"
const password = "thisispassword"

const res = await fetch("http://localhost:4567/auth", {
  headers: {
    Authorization: "Basic " + btoa(`${username}:${password}`)
  }
})
console.log(await res.text())
$ zx script.mjs --quiet
Authorized.

最近よく使っている zx で動作確認した

いつも脳死でコピペしてたけど、よく見たらそんなに難しい書き方じゃないから普通に覚えられるな

補足 🔗

動作確認で使った API は「【Sinatra】ページ単位で Basic 認証を入れる 」で作ったやつを使った

$ curl http://localhost:4567/auth
Unauthorized.

$ curl http://localhost:4567/auth -H "Authorization: Basic $(echo -n 'takagi:thisispassword' | base64)"
Authorized.

【JavaScript】Base64 でエンコード・デコード

JavaScript で文字列を Base64 でエンコード・デコードする機会があったのでメモ

標準で btoa(), atob() が用意されているのでそれを使えばサクッとできる

const text = "Hello"

const encoded = btoa(text)
console.log(encoded) //=> SGVsbG8=

const decoded = atob(encoded)
console.log(decoded) //=> Hello

日本語などのマルチバイトの場合は、さらに encodeURIComponent(), decodeURIComponent() でエンコード・デコードする必要がある

const text = "こんにちは"

const encoded = btoa(encodeURIComponent(text))
console.log(encoded) //=> JUUzJTgxJTkzJUUzJTgyJTkzJUUzJTgxJUFCJUUzJTgxJUExJUUzJTgxJUFG

const decoded = decodeURIComponent(atob(encoded))
console.log(decoded) //=> こんにちは

補足 🔗

  • btoa: binary to ASCII
  • atob: ASCII to binary

参考 🔗

Categories


Tags