tag:crieit.net,2005:https://crieit.net/users/azechi/feed あぜち(おばあちゃん)の投稿 - Crieit Crieitでユーザーあぜち(おばあちゃん)による最近の投稿 2019-05-20T22:20:07+09:00 https://crieit.net/users/azechi/feed tag:crieit.net,2005:PublicArticle/15003 2019-05-20T18:32:12+09:00 2019-05-20T22:20:07+09:00 https://crieit.net/posts/Git-Revert Git Revert 複数コミットをまとめて取り消すときにコミットメッセージを設定する <p>「ここからここまでのコミット」と範囲を指定したrevertをして、いい感じのコミットメッセージを作る方法です。</p> <p>複数のコミットをrevertしたい場合は、単に複数のコミットを指定するか、オプション<code>--no-commit</code>でrevertコマンドを繰り返した後に<code>revert --continue</code>して確定します。どちらの場合も、コミットメッセージをコマンドラインで指定することができません。オプション<code>-e</code>はコミットメッセージを編集するためのエディタを開くもので、メッセージをコマンドラインで指定できません。*コマンドリファレンス <a target="_blank" rel="nofollow noopener" href="https://git-scm.com/docs/git-revert">Git - git-revert Documentation</a></p> <p>メッセージを指定するには、オプション<code>--no-commit</code>を実行した後に通常のコマンド<code>git commit</code>をオプション<code>-m</code>と共に実行します。from: <a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/27507977/specify-commit-message-with-revert-continue">stack overflow</a></p> <p>ところで、gitには「ここからここまでのコミット」を表す記法があります。例えば、<code>master..HEAD</code>の「<code>..</code>」みたいなやつ。詳しくはここに書いてあります、<a target="_blank" rel="nofollow noopener" href="https://git-scm.com/book/ja/v2/Git-のさまざまなツール-リビジョンの選択#コミットの範囲指定">Git Book コミットの範囲指定</a>。revertコマンドでは、この記法で複数コミットを指定できます。</p> <p>以下のコマンドではbashの文字列展開を使って、すべての取り消し対象コミットのメッセージの先頭行を結合したテキストを作ります。</p> <pre><code class="bash">$ ref=[ここまで戻したいコミット、タグ] $ git revert --no-commit $ref..HEAD $ git commit -m "Revert to $ref" -m "$(eval "git log --pretty=oneline $ref..HEAD")" # 確認 $ git diff $ref HEAD </code></pre> <ul> <li><code>revert --no-commit</code>で、チェリーピッキング <ul> <li><code>revert --continue</code>するとメッセージが指定できない</li> </ul></li> <li>commit -mしてしまえばいい <ul> <li><code>-m</code>オプションを複数書いたら改行して追加される</li> </ul></li> <li>bashで入れ子の文字列展開には<code>eval</code>を使う <ul> <li><code>"$(eval "$var")"</code></li> </ul></li> </ul> あぜち(おばあちゃん) tag:crieit.net,2005:PublicArticle/14807 2019-02-18T09:52:00+09:00 2019-02-18T10:39:14+09:00 https://crieit.net/posts/gopls-golps-bingo-gopath-panic gopls(golsp)でもbingoでも、gopathの下でなかったらただpanicで終了する <p>この記事は以下のバージョンで確認した内容です</p> <ul> <li>go version 1.11</li> <li><code>GO111MODULE</code>が<code>ON</code>ではない</li> <li>gopls <a target="_blank" rel="nofollow noopener" href="https://go.googlesource.com/tools/+/8dcb7bc8c7fe0a895995c76c721cef79419ac98a">golang.org/x/tools/cmd/gopls</a> commit: 8dcb7bc</li> </ul> <hr /> <p>VimでGo言語の入力補完がしたくて、vim-lspとgoplsをインストールした。<br /> <code>.go</code>ファイルを開いて動作の確認をしようとしたが補完候補が出なかった。</p> <p>vim-lspのログを見ると、ファイルを開いたときの一連の処理でgoplsが終了していた。<br /> <code>panic: runtime error: invalid memory address or nil pointer dereference</code></p> <h3>原因は、<code>.go</code>ファイルがgopath以下のディレクトリになかったためだった。</h3> <p>Vimの補完プラグインを試すことに注意が向いていたので、golangの基本的なことを忘れていた。</p> <p>※ <a target="_blank" rel="nofollow noopener" href="https://github.com/golang/tools/blob/b258f6da23835bf37e95cc50af792447c7c67fe4/cmd/golsp/main.go#L5-L8">goplsは、golspから名前が変わったもの</a></p> <hr /> <h4>開いた<code>.go</code>ファイルがgopath下になかったときのvim-lspのログ</h4> <pre><code>Mon 18 Feb 2019 08:53:17 AM +09:["lsp#register_server","server registered","go-lang"] ... (中略) ... Mon 18 Feb 2019 08:53:17 AM +09:["s:update_file_content()",1] Mon 18 Feb 2019 08:53:17 AM +09:["--->",1,"go-lang",{"method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///home/user/main.go","version":1,"languageId":"go","text":"\n"<span>}</span><span>}</span>}] Mon 18 Feb 2019 08:53:17 AM +09:[{"response":{"data":{"path":"file:///home/user/main.go","__data__":"vim-lsp","filetype":"go","server_name":"go-lang"},"message":"textDocument/open sent"<span>}</span><span>}</span>] Mon 18 Feb 2019 08:53:17 AM +09:[{"response":{"data":{"path":"file:///home/user/main.go","__data__":"vim-lsp","server_name":"go-lang"},"message":"not dirty"<span>}</span><span>}</span>] Mon 18 Feb 2019 08:53:17 AM +09:["<---(stderr)",1,"go-lang",["[Trace - 8:53:17 AM] Sending notification 'textDocument/didOpen'.\r","Params: {\"textDocument\":{\"uri\":\"file:///home/user/main.go\",\"version\":1,\"languageId\":\"go\",\"text\":\"\\n\"<span>}</span><span>}</span>\r","\r","\r",""]] Mon 18 Feb 2019 08:53:17 AM +09:["<---(stderr)",1,"go-lang",["panic: runtime error: invalid memory address or nil pointer dereference","[signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0x6e894d]","","goroutine 7 [running]:","golang.org/x/tools/internal/lsp/source.Diagnostics(0x8b4f00, 0xc00001a0d8, 0x8b5040, 0xc00007e090, 0xc000018ce0, 0x1d, 0xc000034740, 0x1, 0x5d789e)","\t/home/user/gopath/src/golang.org/x/tools/internal/lsp/source/diagnostics.go:56 +0xcd","golang.org/x/tools/internal/lsp.(*server).cacheAndDiagnose.func1(0x8b4f00, 0xc00001a0d8, 0xc000051480, 0xc000018ce0, 0x1d)","\t/home/user/gopath/src/golang.org/x/tools/internal/lsp/diagnostics.go:24 +0x81","created by golang.org/x/tools/internal/lsp.(*server).cacheAndDiagnose","\t/home/user/gopath/src/golang.org/x/tools/internal/lsp/diagnostics.go:23 +0x13c",""]] Mon 18 Feb 2019 08:53:17 AM +09:["s:on_exit",1,"go-lang","exited",2] Mon 18 Feb 2019 08:53:20 AM +09:["s:on_text_document_did_close()",1] </code></pre> あぜち(おばあちゃん) tag:crieit.net,2005:PublicArticle/14640 2018-12-10T19:27:50+09:00 2018-12-10T19:37:15+09:00 https://crieit.net/posts/discord-bot ブラウザでdiscord botを作れるんだよ <p>Google Cloud Shell で Discord.pyを使ってDiscord Botを作る。</p> <ul> <li>Google Cloud Shellには、最初からpython3とpipはインストール済み。</li> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/Rapptz/discord.py">Discord.py</a>はPythonで書かれたDiscord APIのラッパー。<a target="_blank" rel="nofollow noopener" href="https://discordapp.com/developers/docs/topics/community-resources#libraries">公認ライブラリ</a>のひとつ。</li> <li>プロジェクトでのPythonパッケージ管理をするためにpipenvを使う</li> </ul> <h3 id="用意するもの"><a href="#%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE">用意するもの</a></h3> <p>Google Cloud Platformのアカウント<br /> Discord botのtoken</p> <h3 id="Google Cloud Shell環境"><a href="#Google+Cloud+Shell%E7%92%B0%E5%A2%83">Google Cloud Shell環境</a></h3> <ul> <li>OSはDebian-based Linux</li> <li>python3は、<code>python3</code>、python3のpipは、<code>pip3</code>という名前で用意されている</li> <li>Google Cloud Shell は起動の度にHOMEディレクトリ(<code>~/</code>)以外は真っさらになる</li> </ul> <h3 id="pipenvをインストールする"><a href="#pipenv%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B">pipenvをインストールする</a></h3> <p>pipenvをユーザーディレクトリへインストールする。</p> <pre><code class="sh">$ pip3 install --user pipenv </code></pre> <p><code>--user</code>オプションを付ければ<code>~/.local</code>以下にインストールされる。</p> <p>PATHに<code>~/.local/bin</code>を追加する。<code>.profile</code>ファイルに、<code>PATH=$PATH:$HOME/.local/bin</code>を書き足す。<br /> ログインしなおすか、<code>$ source .profile</code>する。</p> <h3 id="プロジェクトへdiscord.pyをインストールする"><a href="#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%B8discord.py%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B">プロジェクトへdiscord.pyをインストールする</a></h3> <pre><code>$ mkdir discord_bot $ cd discord_bot $ pipenv install https://github.com/Rapptz/discord.py/archive/master.zip#egg=discord.py </code></pre> <p>自分はボイスチャット機能を使いたいから、<code>https://github.com/Rapptz/discord.py/archive/master.zip#egg=discord.py[voice]</code>とした。</p> <h3 id="できあがり"><a href="#%E3%81%A7%E3%81%8D%E3%81%82%E3%81%8C%E3%82%8A">できあがり</a></h3> <pre><code>import discord </code></pre> <p>してコード書けばいい。</p> <p>実行するときは</p> <pre><code>$ pipenv run python main.py </code></pre> <hr /> <hr /> <h3 id="※うまくいかなかったやりかた"><a href="#%E2%80%BB%E3%81%86%E3%81%BE%E3%81%8F%E3%81%84%E3%81%8B%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E3%82%84%E3%82%8A%E3%81%8B%E3%81%9F">※うまくいかなかったやりかた</a></h3> <pre><code>$ pipenv install discord.py </code></pre> <p>したら、エラー<code>ERROR: ERROR: Could not find a version that matches discord-py</code>が発生した。<br /> わからない。<br /> <a target="_blank" rel="nofollow noopener" href="https://pypi.org/project/discord.py/">pypiのdiscord.pyページ</a>にあるurlを指定する書き方を試したらできた。</p> <h3 id="※※ pypiは、パイピーアイと呼ぶ人が多いらしいとどこかで聞いた。pypyというのがあって、そっちがパイパイ。"><a href="#%E2%80%BB%E2%80%BB+pypi%E3%81%AF%E3%80%81%E3%83%91%E3%82%A4%E3%83%94%E3%83%BC%E3%82%A2%E3%82%A4%E3%81%A8%E5%91%BC%E3%81%B6%E4%BA%BA%E3%81%8C%E5%A4%9A%E3%81%84%E3%82%89%E3%81%97%E3%81%84%E3%81%A8%E3%81%A9%E3%81%93%E3%81%8B%E3%81%A7%E8%81%9E%E3%81%84%E3%81%9F%E3%80%82pypy%E3%81%A8%E3%81%84%E3%81%86%E3%81%AE%E3%81%8C%E3%81%82%E3%81%A3%E3%81%A6%E3%80%81%E3%81%9D%E3%81%A3%E3%81%A1%E3%81%8C%E3%83%91%E3%82%A4%E3%83%91%E3%82%A4%E3%80%82">※※ pypiは、パイピーアイと呼ぶ人が多いらしいとどこかで聞いた。pypyというのがあって、そっちがパイパイ。</a></h3> <h3 id="※※※pipenvをインストールしたり、pip3自体を更新すると、pip3コマンドが使えなくなる。"><a href="#%E2%80%BB%E2%80%BB%E2%80%BBpipenv%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%9F%E3%82%8A%E3%80%81pip3%E8%87%AA%E4%BD%93%E3%82%92%E6%9B%B4%E6%96%B0%E3%81%99%E3%82%8B%E3%81%A8%E3%80%81pip3%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8C%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%8F%E3%81%AA%E3%82%8B%E3%80%82">※※※pipenvをインストールしたり、pip3自体を更新すると、pip3コマンドが使えなくなる。</a></h3> <p>そのときは代わりにこう書けばpip3コマンドと同じ。</p> <pre><code>$ python3 -m pip PIPCOMMAND ARGS </code></pre> あぜち(おばあちゃん) tag:crieit.net,2005:PublicArticle/14604 2018-11-15T10:25:03+09:00 2018-11-16T16:55:42+09:00 https://crieit.net/posts/vim-tmux vimとかtmuxとかを使いこなそうとしない <p>Google Cloud Shellの中でやれることをやる。高価なPCやサーバーを用意しなくてもブラウザだけで従来の「プログラミング」をすることができる。評価の定まった本に書かれたコードを書いて実行できる。いま始める人のためにピッタリ。</p> <p>Google Cloud ShellにはWebエディターも用意されているけど複雑だから使わない。<br /> vimがインストール済みだからvimを使う。</p> <pre><code class="bash">$ vim index.html </code></pre> <p>ややこしいことは考えずに、<br /> <code>ESC</code>と<code>i</code>と<code>:q!</code>と<code>:qw</code>だけで十分使える。<br /> ESCキーの代わりに使える<code>ctrl + [</code> が便利。</p> <p>設定しなくても色が付いてるし、自動で閉じタグ書いてくれる。<br /> ただ、タブ幅が大きすぎるからvimrcファイルで設定する。</p> <p><code>~/.vim/vimrc</code>ファイルを置く、中身は3行。</p> <pre><code>source $VIMRUNTIME/defaults.vim </code></pre> <p>まずこれを書くこと。これがないとすっぴんで起動して、htmlのハイライトもされない。</p> <pre><code>set tabstop=4 set shiftwidth=0 </code></pre> <p>これでタブ1文字の表示がスペース4つ分になる。</p> <p>index.htmlを書いたら、プレビューする。</p> <p>Google Cloud Shellの「ウェブでプレビュー」は、インターネットからアクセスできるURLを用意してくれる。googleアカウントでログイン済みのアクセスだけをcloud shellの8080ポートへ通してくれる。<br /> ということで、8080ポートで待ち受けするWebサーバーを起動する。何を使ってもいいんだけど、インストールされててすぐ使えるからpython3。</p> <pre><code>$ python3 -m http.server 8080 </code></pre> <p>実行すると、画面から入力待ちのプロンプトが消えてWebサーバーのログが表示されるようになる。こうなるとvimが使えない。Webサーバーを起動したままで他のこともしたい。cloud shellの別のタブを使ってもいいけど、Google Cloud Shellはtmuxが導入済みで、こういう場面で役に立つ。</p> <p><code>ctrl + b, c</code>を押すと、「Wellcome to Cloud Shell」が表示される。さっきまでの画面は<code>ctrl + b, n</code>で戻れる。迷子になったときは<code>ctrl + b, w</code>で画面の一覧が出せる。</p> <p>これで、Webサーバーを起動させたままvimでhtmlファイルを編集できる。</p> <p>vimを終了させずにファイルを保存するには、<code>:w</code></p> あぜち(おばあちゃん) tag:crieit.net,2005:PublicArticle/14591 2018-11-02T15:43:53+09:00 2018-11-02T15:43:53+09:00 https://crieit.net/posts/window-is-not-equal-to 「window is not equal to」というログメッセージ <p>ログに"window is not equal to"というメッセージが出力された。windowとあるので、Storyboardに問題があるのかと思ったが違った。また、メッセージの中にあるViewControllerが原因でもなかった。遷移元のViewControllerでperformSegue(withIdentifier:sender:)を2回呼んでいたことが原因だった。</p> <blockquote> <p>'s window is not equal to 's view's window!</p> </blockquote> <h3 id="ヒントになった"><a href="#%E3%83%92%E3%83%B3%E3%83%88%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F">ヒントになった</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://teratail.com/questions/12348">teratail「window is not equal to」というログメッセージ</a></p> <h3 id="問題のコード"><a href="#%E5%95%8F%E9%A1%8C%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89">問題のコード</a></h3> <pre><code class="swift">if user == nil { self.performSegue(withIdentifier: "segueA", sender: nil) return // このreturnを忘れた } self.performSegue(withIdentifier: "segueB", sender: nil) // 終了 </code></pre> <p>今回のケースでは、userがnilでないときに追加して他のことをするならguard文で書くのが妥当。上記のコードでは、遷移先の選択のみなので、guard文ではなくif else で並列に書くと意図が明確になると思う。</p> あぜち(おばあちゃん) tag:crieit.net,2005:PublicArticle/14582 2018-10-24T17:32:13+09:00 2018-11-12T10:41:44+09:00 https://crieit.net/posts/iOS-5bd02e0d95c05 自家用iOSアプリの開発をはじめられるようなサンプルアプリケーションを作るぞ <h3 id="20181112 追記"><a href="#20181112+%E8%BF%BD%E8%A8%98">20181112 追記</a></h3> <p>やっぱり面倒になってやめた。コードの断片をメモにして残しておくことにする。自分で使うつもりもないアプリなんて作れない。ニーズを想定できないから細かい部分で判断に迷ってしまってうまく進められなかった。今後もアプリを作る気がないし。</p> <p>↑ 追記おわり</p> <p>夏ごろに人に頼まれて初めてiOSアプリを作った。そのアプリは結局没になったのだけれど。せっかく勉強したので何か形に残しておこうと思った。</p> <p>iOSアプリ開発の初心者向けのサンプルアプリを書いてる。頼まれて仕事として作るアプリではなくて、MacとiPhone持ってて自分で使うアプリ作れたらいいなって人にワークショップとかできたら金になるかな、なんて野心もあったり。</p> <p>いまはまず、最初の1回目をざっくり作ってみてる。その後コードを捨ててまた同じものを書きながらキレイなコミットログを作ったり、リファクタリングの台本とか考えてみようと思ってる。</p> <p>アプリは出納帳。ものの出し入れの数量を記録する。こづかい帳として使えるもの。それだけだとつまらないから、Firebase Cloud Firestoreをデータ置き場にする。iOSアプリとは別でWebアプリのサンプルアプリも作って連携できるようにしたら面白そうだから。</p> <p>UIは、iOSの設定アプリにならう。全部UITableView。なるべくInterfaceBuilderだけで出来るようにする。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/azechi/suito-cho">ソースコード@github</a><br /> ご意見下さい。</p> あぜち(おばあちゃん) tag:crieit.net,2005:PublicArticle/14580 2018-10-24T11:05:11+09:00 2018-10-31T10:45:15+09:00 https://crieit.net/posts/Swift-Static 手探りSwift: Staticメンバーをクラス内で呼ぶときにクラス名を書かなくちゃいけない <p>Swiftはstaticメンバーをクラス内で呼ぶときに、C#のようにメンバー名だけでは呼べなくて<code>className.memberName</code>のように書かなくてはいけない。これが馴染めない。タイプ数を問題にしているのではない。</p> <p>クラスの内側でクラス名が出てくると遠近が混乱して頭に余計な負荷がかかる。クラス名は外側の名前なのに、内側で出てくると他の内側の構成要素の語彙と馴染まない。固有名詞を出す必要のない場面で固有名詞が登場する。代名詞で十分である。</p> <p>あまりいいアイデアとも思えないけど、いい方法が見付かるまでの次善の策を思いついた。<br /> クラス名に外側の意味を持たない別名を付ける。下の例だと<code>Type</code>だけど、これは<code>Static</code>でも、<code>Class</code>でもなんでもいい。</p> <p>typealiasは実行時コストがゼロ(?)だから、純粋に表現の問題として扱える...はず。<br /> staticメンバーにアクセスするインスタンスメンバーを用意する方法もあると思う。そちらもコンパイル時の最適化によってコストゼロになりそうだけど、今の自分では判断ができなかったので避けた。</p> <h1 id="例"><a href="#%E4%BE%8B">例</a></h1> <p>こういう POSOがあったとして</p> <pre><code class="swift">struct Supercalifragilisticexpialidocious { var dateStr = "" } </code></pre> <h3 id="Before"><a href="#Before">Before</a></h3> <pre><code class="swift">import Foundation extension Supercalifragilisticexpialidocious { private static var df = ISO8601DateFormatter() var date: Date? { get { return Supercalifragilisticexpialidocious.df.date(from: dateStr) } set { dateStr = Supercalifragilisticexpialidocious.df.string(from: dateStr) } } } </code></pre> <p>DateFormatterのインスタスをstatic変数<code>df</code>にキャッシュしておく。プロパティ<code>date</code>では、<code>df</code>を使って文字列と日付を変換する。<code>df</code>はprivate変数であり内側の構成要素なのだけど、<code>Supercalifragilisticexpialidocious</code>と書かれていることで<code>df</code>が今のスコープの外側のモノという錯覚が生れる。</p> <h3 id="After"><a href="#After">After</a></h3> <pre><code class="swift">import Foundation extension Supercalifragilisticexpialidocious { fileprivate typealias `Type` = Supercalifragilisticexpialidocious private static var df = ISO8601DateFormatter() var date: Date? { get { return Type.df.date(from: dateStr) } set { dateStr = Type.df.string(from: dateStr) } } } </code></pre> <p>自クラスを<code>Type</code>という代名詞で指せるようになった。<br /> 言語の上に、自分ルールを置くことによってコードを読むときのスコープが狭まって読みやすくなったと思う。ただしルールは増えたし、そのルールは自分しか知らない。</p> あぜち(おばあちゃん)