2019年9月11日水曜日

No such module RealmSwift

概要

いつも対処方法を忘れるのでメモ

環境

  • macOS 10.14.6
  • Xcode 10.3

対処方法

Pods -> RealmSwift -> Build Settings -> Build Active Architecture Only -> No

もしくは

Pods -> Pods -> Build Settings -> Build Active Architecture Only -> No

上記以外にも試す価値あり

  • rm -rf Pods
  • pod update

そして Xcode を再起動します

2019年9月10日火曜日

どんなときも Wifi レビュー

概要

1 ヶ月ほど使ったので備忘録として残しておきます

Good

通信制限がない

100GB 制限とか 3 日で 7GB 制限などはないので常時出せるだけ出してくれます

速度は平均 10Mbps くらい

平均すると 10Mbps くらいは常時でます
平日昼間の空いている時間がおそらくピークで 20 - 30 Mbps は出ます
夜のゴールデンタイムはやはりベストエフォートなのか 1 - 5Mbps くらいしか出ないときもザラにあります
ですが 128kpbs などのよくある通信制限状態になることはありません

Bad

クラウド SIM なので障害がある

2019/08/31 - 2019/09/03 あたりで公式からアナウンスもあったのですがクラウド SIM なのでクラウド側に障害が発生すると通信もできなくなります
頻繁にあるわけではないですがクラウド起因だということを理解しておく必要があります
公式でどのクラウドを使っているなどの紹介はありませんが障害の発生日時などを照らし合わせるとある程度は絞り込めるかも?

Mac App Store に接続できない? -> macOS のアップデートができなかった

最近あった 10.14.6 の追加アップデートができませんでした
D1 というルータに防護機能がありこれを OFF にするとできるという情報があったのですが OFF にしてもダメでした
iOS アプリのアップデートはできたので macOS だけダメなような気がします

キャリアの選択はできない、回線の違による検証とかできたらよかった

仕様では「最適」なキャリアを選択するとあるのですがこれを自分で選択することはできません
docomo or au or Softbank なのですが例えばキャリアの違いによる検証をしたい場合に手動で切り替えたりはできません
日常使いする分には手動で切り替える必要全くないですが機能としてあると嬉しいなと思った感じです

D1 がダメ

同時接続が「5台」しかないのが最大の痛手です
自分はラズパイを一つ使って hostapd でアクセスポイントを増やしています (参考)
これだと無限に接続できますがラズパイのスペックがある程度要求されるのでご注意ください
また記事でも書いていますがラズパイ経由の通信は速度が 1/10 くらいになってしまうので正直限られたことしかできないです

あとはルータとしての機能もそこまで多くないです
Static Routing やポートフォーワド、VPN パススルーのような機能はなかった気がします

契約に縛りあり

2 年契約です
2 年後は割引も解消されてしまいます
そのタイミングで乗り換えを検討するのはありだと思います

月間の利用容量がわからない

ルータによっては月間でどれくらい使用したかわかるのですが D1 にはないようです
毎日リセットされる?っぽいので自分で忘れずにメモして管理するしかなさそうです

最後に

どんなときも Wifi を 1, 2 ヶ月使ってみた感想を紹介しました
完璧なポケット Wifi は現状ないのでそれを求めてはダメですが現行のポケット Wifi の中ではかなり良い方だと思います
月額料金も他のポケット Wifi と変わりません 
特に通信制限がないのはかなり良いです
ただ速度自体がそこまで出ないので速度を求める場合にはあまりおすすめしません
特にリアルタイムゲームなどをやる場合にはちゃんと固定回線を引きましょう

2019年9月6日金曜日

Sass 超入門

概要

Sass は CSS をプログラマブルに書けるツールです
Sass 形式で書いたファイルを CSS にコンパイルすることで使えるようになります
今回はインストールから簡単なサンプルコードいろいろと実装して実際に動かして試してみました
また Ruby 版の Sass は廃止になり Dart 版が現在はサポート対象なので Dart 版を使います

環境

  • macOS 10.14.6
  • Sass (Dart) 1.22.10

インストール

  • xcode-select --install
  • brew install sass/sass/sass

xcode-select が必要になるのでない場合はインストールしましょう
また Ruby 版の sass がすでにある場合は今回インストールした dart 版で上書きしましょう

  • rm /usr/local/bin/sass
  • brew link sass

テスト用のアプリの作成

なんでも OK です
静的ファイルを配信するだけなので nginx の DocumentRoot でも OK です
今回は Sinatra アプリを作成します

  • bundle init
  • vim Gemfile
gem "sinatra"
  • bundle install --path vendor
  • vim app.rb
require 'sinatra/base'

class Sass < Sinatra::Base
  get '/' do
    erb :index
  end
end
  • vim config.ru
require './app'

run Sass
  • mkdir public
  • mkdir views
  • vim views/index.erb
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="/test.css">
  </head>
  <body>
    <div id="message">hello
      <div class="nested">world</div>
    </div>
  </body>
</html>
  • bundle exec rackup config.ru

で localhost:9292 でアプリで起動します
コンパイルした CSS ファイルは public ディレクトリ配下で配信します

とりあえずコンパイルしてみる

兎にも角にも .sass ファイルコンパイルして .css ファイルを作成してみましょう

  • vim test.sass
#message
  font-size: 24px

ブラケットなどは不要でインデントを使います
あとは sass コマンドを使ってコンパイルします

  • sass test.sass public/test.css

基本的な使い方は sass [input sass file] [output css filie] になります
.css ファイルの他に .css.map というファイルも作成されます
map ファイルは元の sass ファイルがどこにあるのかを記録しておくフィアルになります
これ以外にもたくさんオプションがあるので詳しくは --help オプションで確認してください
(以下同じコマンドでコンパイルするので省略します)

これでアプリを起動して確認してみましょう
先ほどと違ってフォントサイズが大きくなっているのが確認できると思います

変数を使う

スタイルシートで同じ値を使い回すことは多いと思います
変数はいろいろなケースで使えます

$fs: 24px

#message
  font-size: $fs

入れ子にする

階層になっている場合には入れ子として宣言できます

$fs: 24px

#message
  font-size: $fs
  .nested
    color: #13f304

id 属性や class 属性に関してはそのまま使えます

import

複数の .sass ファイルに分けて管理することができます
部分ファイルはアンダースコアから始まるようにしましょう

  • vim _partial.sass
.nested
  margin: 10px
  • vim test.sass
@import 'partial'

$fs: 24px

#message
  font-size: $fs
  .nested
    color: #13f304

@import 'partial' という感じで指定します
import する partial ファイルのアンダースコアは省略できます

ポイントなのは最終的に出力される .css ファイルは import した partial ファイルの順番になります
そして .css は後にかかれている定義が優先的に評価されます
なのでもし test.sass で .nested の margin を再定義している場合はそちらが優先されることになります

四則演算

サイズなどは四則演算が使えます

@import 'partial'

$fs: (24px - 12px)
$width: (100% - 20%)

#message
  width: $width
  font-size: $fs
  .nested
    color: #13f304

基本的には同じ単位でやるのでいいでしょう
パーセントと組み合わせて使うこともできます
ただ (24px - 50%) などはエラーになります

関数

独自の関数も定義できます
引数に応じていろいろと定義を変えたい場合に便利です

@import 'partial'

@function double($value)
  @return $value * 2

$fs: (24px - 12px)
$width: (100% - 20%)

#message
  width: $width
  font-size: $fs
  .nested
    color: #13f304
    font-size: double($fs)

複雑になってきましたが上記は double という関数を定義しています
(24px - 12px) = 12px を渡してそれを倍にした値を font-size にしています
ビルトインの関数もいろいろとあるのでこちらを参照してください

@mixin

関数に似た機能ですが定義したスタイルを別のスタイルに @include することができます

@import 'partial'

@function double($value)
  @return $value * 2

@mixin margin-reset
  margin: 0px

$fs: (24px - 12px)
$width: (100% - 20%)

#message
  width: $width
  font-size: $fs
  .nested
    color: #13f304
    font-size: double($fs)
    @include margin-reset

@mixin で定義して @include で参照します
同じような機能に @extend という機能もあります
どちらがどう使うかはこのあたりの記事が参考になるかもしれません

最後に

Sass に入門してみました
Ruby 版が廃止になったので Dart 版を使っています
変数や関数を使ってごちゃごちゃになった CSS をキレイに書くことができると思います
面倒なのはコンパイルする必要がある点なのでビルドフローがあれば忘れないように入れるようにしましょう
また --watch という機能もあるので更新するたびにコンパイルすることもできます

まだ Web 上には Ruby 版の情報がちらほらあるのでドキュメントは基本的に公式のものを使いましょう

参考サイト

2019年9月5日木曜日

golang で環境変数のデフォルト値を設定する方法

概要

Ruby で言うところの

v = ENV['VALUE'] || 'hoge'

です

環境

  • macOS 10.14.6
  • golang 1.12.9

サンプルコード

専用の関数を作成すれば OK です

package main

import (
    "fmt"
    "os"
)

func getEnv(key, fallback string) string {
    if value, ok := os.LookupEnv(key); ok {
        return value
    }
    return fallback
}

func main() {
    v := getEnv("VALUE", "fuga")
    fmt.Println(v)
}

参考サイト

2019年9月4日水曜日

go-workers で SIGINT や SIGHUP のシグナルをハンドリングする方法

概要

go-workers でシグナルをハンドリングする方法を紹介します

環境

  • macOS 10.14.6
  • go 1.12.9
    • go-workers dbf81d0b75bbe2fd90ef66a07643dd70cb42a88a

go-workers 内でハンドリングしてくれるシグナル

実は go-workers 内でも特定の Ctrl+c などのシグナルはハンドリングしてくれています

func handleSignals() {
        signals := make(chan os.Signal, 1)
        signal.Notify(signals, syscall.SIGUSR1, syscall.SIGINT, syscall.SIGTERM)

        for sig := range signals {
                switch sig {
                case syscall.SIGINT, syscall.SIGUSR1, syscall.SIGTERM:
                        Quit()
                }
        }
}

この関数はワーカーが Run() した際に goroutine として実行されています
Ctrl+c は syscall.SIGINT になります
やっていることは単純で Quit() という処理を実行してワーカーが正しく終了されるような処理を実行しています

ただ SIGHUP などはハンドリングしていないのでワーカーに SIGHUP を送信すると「Hungup: 1」と表示されて終了してしまいます
しかも go run で実行しているとビルドのプロセスが残ってしまい面倒なことになります
なので他のシグナルも本当はちゃんとハンドリングしてあげる必要がありそうです

SIGHUP をハンドリングしてみる

試しに SIGHUP を追加でハンドリングできるようにしていみます
特にライブラリに手を入れる必要はなくワーカー側でハンドリングするようにすれば OK です

package main

import (
    "os"
    "os/signal"
    "syscall"

    "github.com/jrallison/go-workers"
)

func handleSignals() {
    signals := make(chan os.Signal, 1)
    signal.Notify(signals, syscall.SIGHUP)
    for sig := range signals {
        switch sig {
        case syscall.SIGHUP:
            workers.Logger.Println("sighup")
        }
    }
}

func perform(msg *workers.Msg) {
    c, _ := msg.Args().Int()
    for i := 0; i < c; i++ {
        workers.Logger.Println(i)
    }
    workers.Logger.Println("end")
}

func main() {
    workers.Configure(map[string]string{
        "server":  "localhost:6379",
        "process": "1",
    })
    workers.Process("default", perform, 1)
    go handleSignals()
    workers.Run()
}

handleSignals 関数をそのまま使って syscall.SIGHUP をハンドリングできるようにします
また main() 内で Run() する前に goroutine として関数を実行しておきます

動作確認

ワーカーを起動して SIGHUP シグナルを送信してみましょう

  • go fmt ./... && go build worker.go && ./worker
  • kill -SIGHUP `ps aux | grep './worker' | grep -v grep | awk '{print $2}'`
workers: 2019/09/04 09:15:55.161765 processing queue default with 1 workers. workers: 2019/09/04 09:15:59.230297 sighup

こんな感じで表示されます
またハンドリングしていない場合はプロセス自体が終了していたのですが今度は終了しなくなったと思います

SIGINT を独自にハンドリングしてみる

go-workers 側で SIGINT をハンドリングしていますが自信でもハンドリングしたいケースはあると思います
先程のワーカーの handleSignals 関数に syscall.SIGINT も追加してみます

func handleSignals() {
    signals := make(chan os.Signal, 1)
    signal.Notify(signals, syscall.SIGHUP, syscall.SIGINT)
    for sig := range signals {
        switch sig {
        case syscall.SIGHUP:
            workers.Logger.Println("sighup")
        case syscall.SIGINT:
            workers.Logger.Println("sigint")
        }
    }
}

動作確認

  • go fmt ./... && go build worker.go && ./worker
  • kill -SIGINT `ps aux | grep './worker' | grep -v grep | awk '{print $2}'`
workers: 2019/09/04 09:32:23.858982 processing queue default with 1 workers. workers: 2019/09/04 09:35:47.852373 sigint workers: 2019/09/04 09:35:47.852375 quitting queue default (waiting for 0 / 1 workers).

ちゃんと SIGINT を独自でハンドリングできました
が、独自のハンドラを抜けてライブラリ側のハンドラーにも行ってしまうようでワーカーは終了してしまいました
たぶん golang の仕様だと思うのですがシグナルのハンドラが複数 goroutine で動いている場合はすべての goroutine がシグナルをキャッチできるんだと思います

なので使い方としては SIGINT の終了前に何か処理をしたい場合に使う感じかなと思います

最後に

go-workers でシグナルをハンドリングする方法を紹介しました
コードを見ると AfterQuit という関数がコメントアウトされていたので始めはミドルウェア的な使い方でハンドリングできるのかなと思ったのですがどうやらダメそうです
今回紹介した方法はライブラリ側でシグナルハンドリングが行われる前に何かする方法になります
なのでライブラリ側で処理した後に何かしたい場合は直接コードを書き換えるしかなさそうで

2019年9月2日月曜日

GIMP でベクターシルエットを作成する方法

概要

GIMP のパスツールを使ってマウスだけでベクターシルエットを作成する方法を紹介します

環境

  • macOS 10.14.6
  • GIMP 2.8

GIMP のインストール

過去に紹介しているのでこちらを参照してください
本記事内では Mac を想定していますがおそらく Windows でも同じようにできると思います

GIMP を起動する

3 つのウィンドウ (ツールボックス、画像、レイヤー) が開けば OK です

対象のファイルを開く

ツールバーから「ファイル」->「開く/インポート」で対象のファイルを開きましょう

パスツールを選択する

ツールボックスからパスツールを選択します
ペンと白い線が描かれているアイコンを選択しましょう
また右ペインのレイヤーウィンドウのタブから「パス」専用のタブを選択しましょう

パスツールで縁を取っていく

これがメインの作業です

基本的な流れは

  • 始点の選択
  • 終点の選択
  • パスを曲げて縁に合わせる

を繰り返します
また画像が小さい場合は拡大しながらやると楽になります
パスを曲げる場合はつないだ線をドラッグすると自由に曲げられます
また始点 or 終点から出ている黄色い線をドラッグするとその点を中心にパスを曲げられるのでそれを使って更に調整します
黄色い線が出てこない場合は先に白い線を曲げてからやると黄色い線も操作できるようになると思います

次のパスを前のパスと接続する場合先に終点を決めて接続する点と Command ボタンを押しながら左クリックするとパス同士を簡単に接続できます

あとはこれをひたすら続けていきます
すべてつなげて囲めたら OK です

パスを選択範囲にする

パスで縁を囲めたら囲んだ部分を選択範囲にします
ツールバーから「選択」->「パスを選択範囲に」を選択します
すると作成したパスの部分が選択範囲になります

選択した範囲を塗りつぶす

あとはこの部分をペイント同様塗りつぶせば OK です
ここからはレイヤーで作業します
まずは右ペインの「パス」タブから「レイヤー」タブに戻します

そして「新しいレイヤーを画像に追加します」というボタンを選択しレイヤーを新規で追加します

塗りつぶす

左ペインのツールボックスから「塗りつぶし」を選択します
今回は単色で塗りつぶすので塗りつぶしの色「描画色」を選択しておきます
色は好きな色を選択しましょう

右ペインからオリジナルの画像を非表示にし塗りつぶす用のレイヤーを表示してアクティブにしておきます
目のボタンをクリックすると非表示にできます

あとは選択範囲の部分を選択して塗りつぶせば OK です

背景色を設定する

新規でレイヤーを追加して背景色を入れても良いでしょう
また選択範囲は「選択」->「選択範囲の解除」でなくしておきましょう

あとはレイヤーの順番を調整して以下のようになれば完成です

png エクスポートする

GIMP の場合パス情報などを含んだファイルは .xcf ファイルとして保存されます
画像ファイルがほしい場合はエクスポートする必要があります
「ファイル」->「エクスポート」を選択し好きな拡張子を選択しましょう

完成

元のサイズと同じサイズのベクターシルエットが作成できます
慣れれば複雑な形でもキレイに作成できると思います

最後に

GIMP のパスツールを使って昔はやった iPod 風のベクターシルエットを作成する方法を紹介しました
自由選択で範囲を作成しているだけなので Adobe Photoshop など高機能なツールを持っている人は自動で切り取ることも可能だと思います

GIMP は無料で使えて高機能なのでそれでここまでできれば十分かなと思います

2019年9月1日日曜日

go-workers でカスタムログを設定する方法

概要

Sidekiq と互換性のある golang 製の go-workers でカスタムロギングを設定する方法を紹介します

環境

  • macOS 10.14.6
  • go 1.12.9

通常の場合

package main

import (
    "github.com/jrallison/go-workers"
    "time"
)

func perform(msg *workers.Msg) {
    c, _ := msg.Args().Int()
    for i := 0; i < c; i++ {
        time.Sleep(1 * time.Second)
        workers.Logger.Println(i)
    }
    workers.Logger.Println("end")
}

func main() {
    workers.Configure(map[string]string{
        "server":  "localhost:6379",
        "process": "1",
    })
    workers.Process("default", perform, 1)
    workers.Run()
}

これで実行すると以下のようなフォーマットで表示されます

workers: 2019/08/30 15:35:04.775722 processing queue default with 1 workers. workers: 2019/08/30 15:35:08.105867 default JID-e00935689dcbdb78123b2ad8 start workers: 2019/08/30 15:35:08.105963 default JID-e00935689dcbdb78123b2ad8 args: 5 workers: 2019/08/30 15:35:09.109906 0 workers: 2019/08/30 15:35:10.113329 1 workers: 2019/08/30 15:35:11.117978 2 workers: 2019/08/30 15:35:12.119421 3 workers: 2019/08/30 15:35:13.124138 4 workers: 2019/08/30 15:35:13.124182 end workers: 2019/08/30 15:35:13.124655 default JID-e00935689dcbdb78123b2ad8 done: 5.01861994s

これをいろいろとカスタムしてみたいと思います

そもそもカスタムするには

公式の issue に回答があります
基本的には workers.Logger に好きな logger を設定すれば OK です
それ以外にも Println と Printf を実装した構造体を設定しても OK です
後者のほうがより自分でカスタマイズできます

特定の値を常に入れる

例えばファイル名と実行行数を入れたい場合には以下のようにします

package main

import (
    "github.com/jrallison/go-workers"
    "log"
    "os"
    "time"
)

func perform(msg *workers.Msg) {
    c, _ := msg.Args().Int()
    for i := 0; i < c; i++ {
        time.Sleep(1 * time.Second)
        workers.Logger.Println(i)
    }
    workers.Logger.Println("end")
}

func main() {
    logger := log.New(os.Stdout, "workers: ", log.Ldate|log.Lmicroseconds)
    logger.SetFlags(log.LstdFlags | log.Lshortfile)
    workers.Logger = logger
    workers.Configure(map[string]string{
        "server":  "localhost:6379",
        "process": "1",
    })
    workers.Process("default", perform, 1)
    workers.Run()
}

=> workers: 2019/08/30 16:22:49 manager.go:53: processing queue default with 1 workers.

標準の log パッケージを使って logger を作成し SetFlags でファイル名と行数を出力するようにしています
こんな感じで好きなロギングパッケージを workers.Logger に設定することでカスタムできます

Println と Printf を実装する

もうひとつの方法を紹介します
こちらのほうがカスタマイズ性は高いですが考慮することが多いので面倒でもあります
構造体を一つ定義しそこに Println と Printf 関数を実装します

package main

import (
    "encoding/json"
    "fmt"
    "github.com/jrallison/go-workers"
    "strconv"
    "sync"
    "time"
)

type MyLogger struct {
}

func (l *MyLogger) Println(v ...interface{}) {
    m := map[string]string{}
    for i, vv := range v {
        switch vv.(type) {
        case string:
            m["msg"+strconv.Itoa(i)] = vv.(string)
        case int:
            m["msg"+strconv.Itoa(i)] = strconv.Itoa((vv.(int)))
        }
    }
    j, _ := json.Marshal(m)
    fmt.Println(string(j))
}
func (l *MyLogger) Printf(fmt string, v ...interface{}) {
    // noop
}

func waiter(i int) {
    t := time.Duration(i)
    time.Sleep(t * time.Second)
    workers.Logger.Println(i)
}

func perform(msg *workers.Msg) {
    c, _ := msg.Args().Int()
    var wg sync.WaitGroup
    for i := 0; i < c; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            waiter(i)
        }(i)
    }
    wg.Wait()
    workers.Logger.Println("end")
}

func main() {
    workers.Logger = &MyLogger{}
    workers.Configure(map[string]string{
        "server":  "localhost:6379",
        "process": "1",
    })
    workers.Process("default", perform, 1)
    workers.Run()
}

=> {"msg0":"processing queue","msg1":"default","msg2":"with","msg3":"1","msg4":"workers."}

[]interface{} で渡ってくるので型を意識する必要があります
今回は JSON に変換していますがそれが目的であればサードパーティのパッケージを使ったほうが良いかなと思います
また上記では Println 関数しか実装していませんが Printf も使うのであれば実装しましょう

最後に

go-workers でロギングをカスタマイズする方法を紹介しました
個人的には workers.Logger をロギングパッケージで上書きする方法が簡単で良いかなと思います
自分でロガーを作成したい場合は後者の Println を実装する方法をおすすめします

参考サイト