tag:crieit.net,2005:https://crieit.net/users/hammhiko/feed
hammhikoの投稿 - Crieit
Crieitでユーザーhammhikoによる最近の投稿
2021-01-26T20:25:54+09:00
https://crieit.net/users/hammhiko/feed
tag:crieit.net,2005:PublicArticle/16651
2021-01-26T20:25:54+09:00
2021-01-26T20:25:54+09:00
https://crieit.net/posts/Bulma-Nuxt-Content-Prism-js
BulmaとNuxt/Content(というかPrism.js)の相性が結構辛い
<h2 id="環境"><a href="#%E7%92%B0%E5%A2%83">環境</a></h2>
<ul>
<li>nuxt: 2.14.6</li>
<li>nuxt/content: 1.9.0</li>
<li>prism-themes: 1.5.0</li>
<li>nuxt-buefy: 0.4.3</li>
</ul>
<h2 id="デザイン大崩れ"><a href="#%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E5%A4%A7%E5%B4%A9%E3%82%8C">デザイン大崩れ</a></h2>
<p>Nuxt/Contentを使っていて、かなり苦戦した。特にNuxt/Contentが内包している、Prism.jsでコードのハイライトを出そうとしたときが辛かった。<br />
<a href="https://crieit.now.sh/upload_images/8ab28d65442b113bed0f81d1e532434a5ff697044862b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8ab28d65442b113bed0f81d1e532434a5ff697044862b.png?mw=700" alt="image" /></a><br />
これ、酷くない?</p>
<p>最初、何か設定をミスったのかと思って、prismの導入あたりのドキュメントを見ても問題ないし、じゃあ、何かのバグかっていうと、突拍子もなさすぎて訳わからん。<br />
しばらく悩んで気がついた。<br />
Bulmaのスタイルが当たってるんだ。<br />
どうやらnumberというクラスが競合しているようだ。<br />
(正直、このnumberクラス、ドキュメントにもないし、初めて見た。そして、何というか、今後使うことなさそう……)<br />
他にもtagというクラスが競合するらしい(未確認)。</p>
<p>cssに関しては大の苦手なので、具体的な施策を提示する自信がないのですが、<br />
とりあえず、Bulmaのスタイルより優先度上のセレクタで上書きする感じで無理矢理やりました。</p>
<h2 id="結構いました。"><a href="#%E7%B5%90%E6%A7%8B%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82">結構いました。</a></h2>
<p>調べてみたら同じ理由で困った人がちらほら。<br />
<a target="_blank" rel="nofollow noopener" href="https://papadays.com/post/5inybk0imz6r2ycmeoquwn/">Bulmaをやめてしまった人までいる。</a><br />
<a target="_blank" rel="nofollow noopener" href="https://stackoverrun.com/ja/q/9978069">みんな困ってるんだね。</a></p>
<h2 id="他にも"><a href="#%E4%BB%96%E3%81%AB%E3%82%82">他にも</a></h2>
<p>Nuxt/Content側の話で、見出しがやけに右に寄るなあ、てのもあった(画像2行目)<br />
<a href="https://crieit.now.sh/upload_images/7878ba53b27b21fcc3ce1b5c3b49da2e5ff6971d71552.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7878ba53b27b21fcc3ce1b5c3b49da2e5ff6971d71552.png?mw=700" alt="image" /></a><br />
見出しのリンク(h2 > a > span)にiconというクラスが割り当てられていて、そこにBulmaのクラスが当たって幅を持ってしまっていた。<br />
まあ、そもそもNuxt/Contentは「<a target="_blank" rel="nofollow noopener" href="https://content.nuxtjs.org/ja/displaying#style">こういう感じで生成するから自分でデザインしてね</a>」なので良いのだが(自分ではなくBulmaが勝手にやってしまった、というのはあるけど)</p>
<h2 id="感想"><a href="#%E6%84%9F%E6%83%B3">感想</a></h2>
<p>Nuxt/Contentもprismも自分の預かり知らないところでHTMLを構成するので、意図せずCSSフレームワークと競合するのはしんどいなあという感想です。<br />
Nuxt/Contentは<a href="#他にも">上記の通り</a>なんだけど、prismは元々のデザインがあるから辛いなあと。<br />
あと、これでBulmaを辞めるという決断になると、同時にbuefyを辞めるという事になるので、結構辛いなあ。</p>
hammhiko
tag:crieit.net,2005:PublicArticle/16543
2021-01-06T08:13:26+09:00
2021-01-06T08:13:26+09:00
https://crieit.net/posts/Nuxt-Content-5ff4f2969eba2
Nuxt/Contentで日付による範囲検索をしたい
<p>ハマりにハマった。</p>
<h2 id="Nuxt/Content"><a href="#Nuxt%2FContent">Nuxt/Content</a></h2>
<p>最近、Nuxt/Contentというものをお試しで触っている。<br />
Markdownとかでコンテンツをゴリゴリ書いていける、GitベースのヘッドレスCMSとかいうものになるらしい。「GitベースのヘッドレスCMS」とか言われてもよくわからないが、DBではなくGitで管理するということだと思う。<br />
検索とか、なんなら全文検索もできるし結構便利そう。<br />
ただ、<a target="_blank" rel="nofollow noopener" href="https://content.nuxtjs.org/ja">公式ドキュメント</a>以外に日本語の記事が乏しくて、ちょっと苦戦する。<br />
ちょっと、というか、どハマりしてしまった。</p>
<h2 id="ハマった環境"><a href="#%E3%83%8F%E3%83%9E%E3%81%A3%E3%81%9F%E7%92%B0%E5%A2%83">ハマった環境</a></h2>
<ul>
<li>Nuxt: 2.14.6</li>
<li>nuxt/content: 1.9.0</li>
</ul>
<h2 id="日付でコンテンツを絞りたい"><a href="#%E6%97%A5%E4%BB%98%E3%81%A7%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E3%82%92%E7%B5%9E%E3%82%8A%E3%81%9F%E3%81%84">日付でコンテンツを絞りたい</a></h2>
<p>作成日でコンテンツを絞りたかったので、<a target="_blank" rel="nofollow noopener" href="https://content.nuxtjs.org/ja/fetching#wherequery">ドキュメント</a>を参考にクエリを書いた。<br />
ただ、日付の扱い方がよくわからなかったので嫌な予感はしていた。</p>
<pre><code class="javascript">// 例)2020/11の記事を検索したい
const monthStart = new Date("2020-11-01")
const monthEnd = new Date("2020-11-30")
const articles = await $content('articles')
.sortBy('createdAt', 'desc')
.limit(5)
.where({
createdAt: { $and: [{ $gte: monthStart }, { $lte: monthEnd }] },
})
.fetch()
</code></pre>
<p>これで11月に作成した記事の最新5件が取れるはずだった。</p>
<h2 id="けど取れない"><a href="#%E3%81%91%E3%81%A9%E5%8F%96%E3%82%8C%E3%81%AA%E3%81%84">けど取れない</a></h2>
<p>変数articlesの中身は空でした。なんで?<br />
もしかしてDateじゃないのかなとか思って日付形式っぽい文字列にしてみてもダメ。<br />
公式ドキュメントを探し直したけど、特に記述はなく……。<br />
なんなら</p>
<blockquote>
<p>createdAt: DateTime</p>
</blockquote>
<p>とか<a target="_blank" rel="nofollow noopener" href="https://content.nuxtjs.org/ja/writing#%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%83%9E%E3%82%BF%E3%83%BC">書いてある</a>し、どう考えたってDateでしょ。</p>
<h2 id="調べた"><a href="#%E8%AA%BF%E3%81%B9%E3%81%9F">調べた</a></h2>
<p>先述の通り、日本語の記事が乏しいうえ、公式ドキュメントに記載がないので苦戦したのだけど、調べて、見つけた。<br />
あったよ。<br />
ていうか、<a target="_blank" rel="nofollow noopener" href="https://github.com/nuxt/content/issues/437">GitHubのissue</a>だったよ!<br />
まあ、内容としてはissueそのまんまなんだけど、</p>
<pre><code class="js">// 例)2020/11の記事を検索したい
const monthStart = new Date("2020-11-01").valueOf()
const monthEnd = new Date("2020-11-30").valueOf()
const articles = await $content('articles')
.sortBy('createdAt', 'desc')
.limit(5)
.where({
createdAt: { $and: [{ $gte: monthStart }, { $lte: monthEnd }] },
})
.fetch()
</code></pre>
<p>valueOf()なんて初めて使ったよ。てか、初めて知ったよ。<br />
と思って<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/valueOf">調べてみたら</a>、getTime()の方が正しい気がしてきたぞ?</p>
<blockquote>
<p>このメソッドは、Date.prototype.getTime() メソッドと機能的に同等です。<br />
このメソッドは、JavaScript によって内部的に呼ばれ、コード内で明示的に呼ばれることはありません。</p>
</blockquote>
<pre><code class="js">// 例)2020/11の記事を検索したい
const monthStart = new Date("2020-11-01").getTime()
const monthEnd = new Date("2020-11-30").getTime()
const articles = await $content('articles')
.sortBy('createdAt', 'desc')
.limit(5)
.where({
createdAt: { $and: [{ $gte: monthStart }, { $lte: monthEnd }] },
})
.fetch()
</code></pre>
<p>うん、これでも動いた。</p>
<p>あー、UNIXタイムスタンプだったかー。ドキュメントに書いてて欲しいなー。</p>
<h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2>
<p>issuesにはあったけど、日本語の記事があっても良いと思ったので書きました。<br />
探し方が悪いだけかもしれませんが。</p>
hammhiko
tag:crieit.net,2005:PublicArticle/16370
2020-12-16T07:00:10+09:00
2020-12-16T07:00:10+09:00
https://crieit.net/posts/e56bb5509d05d584c2c5ec4f7e6d77a1
辞めないこと
<p>Crieitの<a href="https://crieit.net/advent-calendars/2020/crieit">なんでも Advent Calendar 2020</a>の16日目の記事です。<br />
ちょっと、今年を振り返ってみます。<br />
純度100%のポエムです。</p>
<h2 id="あ、やべー。今年何もしてねえ"><a href="#%E3%81%82%E3%80%81%E3%82%84%E3%81%B9%E3%83%BC%E3%80%82%E4%BB%8A%E5%B9%B4%E4%BD%95%E3%82%82%E3%81%97%E3%81%A6%E3%81%AD%E3%81%88">あ、やべー。今年何もしてねえ</a></h2>
<p>っていうのが今年の総括になってしまいますね……。今年の振り返り、以上。<br />
いや、ちゃんと仕事はしていたんですけど。プログラマのアウトプット的な意味で、何もしていない。<br />
Crieitにも記事を一つ書いただけですし。</p>
<h2 id="でも、誰にも怒られない"><a href="#%E3%81%A7%E3%82%82%E3%80%81%E8%AA%B0%E3%81%AB%E3%82%82%E6%80%92%E3%82%89%E3%82%8C%E3%81%AA%E3%81%84">でも、誰にも怒られない</a></h2>
<p>だって、好きでやっているだけだもの。仕事じゃないもの。<br />
自分の場合は、ゆるーくやっていければそれで良いかなーとは思っています。<br />
似たようなことは<a href="https://crieit.net/posts/localhost#それでも良くね?">去年の今頃も言ってます</a>けど。</p>
<p>とはいえ、好き勝手やっているともちろん悪いこともあって。<br />
それは、「辞めてしまう確率が上がる」ことだと思っています。</p>
<h2 id="大事なのは辞めないこと"><a href="#%E5%A4%A7%E4%BA%8B%E3%81%AA%E3%81%AE%E3%81%AF%E8%BE%9E%E3%82%81%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8">大事なのは辞めないこと</a></h2>
<p>僕の好きな言葉に<br />
<em>1番になりたかったら続けなさい。周りが勝手に辞めていくから</em><br />
というのがあります。<br />
(実は、昔twitterで見かけた言葉で、誰が言ったのかもわからないのですが)<br />
「継続は力なり」とか言われると教訓じみていて少し嫌ですけど、もっと俗っぽい言い回しなので好きです。<br />
1番になれるかとか、なりたいかとかはともかくとして、続けるって大事。辞めないって大事。<br />
さらに言えば、続ける事というか、辞めない事が大事。ちょっとしたニュアンスの違いだけど。</p>
<p>一度辞めてしまうと、再開する時のエネルギーってものすごく必要になると思うんですよね。<br />
再開する資格があるかとか、再開できる環境かどうかとか、そして何より再開する気力が湧くかどうか。<br />
そして結局、再開できない。</p>
<p>「好きでやっているだけだから」と言って、この辺りの事を見失ってしまうと、あっさりと辞めてしまう気がするんです。すると、もう戻って来られない。<br />
だから、好きでやっているだけでも良いけど、これを肝に銘じて続ける。どんなにペースを落としても良いから辞めない。<br />
これが大事なんじゃないかなと思います。</p>
<p>というこの記事を書く事で、僕は今年何もしていなくても、超スローペースでも、何も辞めなかった事にします。</p>
hammhiko
tag:crieit.net,2005:PublicArticle/16007
2020-07-15T21:42:59+09:00
2020-07-15T21:47:11+09:00
https://crieit.net/posts/chrome-UTF-8-5f0ef9d3db43f
続・ブラウザ(chrome)のデフォルトエンコードってUTF-8じゃないの?
<p><strong>かなり雑な考察ですのでご注意ください。</strong></p>
<h2 id="今は昔"><a href="#%E4%BB%8A%E3%81%AF%E6%98%94">今は昔</a></h2>
<p>かつて<a href="https://crieit.net/posts/chrome-UTF-8">ブラウザ(chrome)のデフォルトエンコードってUTF-8じゃないの?</a>という記事を書いたのですが。<br />
こちら、タイトルが疑問文であることからもわかる通り、単なる疑問を書き殴った記事で、解決していません。<br />
ですが、私が書いた他の記事の3倍、4倍ものアクセスがあり、心苦しいというか、「なんだよ、結局わからなかったじゃねえかよ、XXX」みたいに思われてるんだろうなあ、みたいな被害妄想をする日々でして。<br />
なので、もう少しだけ頑張ってみようと思います。</p>
<h2 id="先に結論(推測)"><a href="#%E5%85%88%E3%81%AB%E7%B5%90%E8%AB%96%EF%BC%88%E6%8E%A8%E6%B8%AC%EF%BC%89">先に結論(推測)</a></h2>
<ul>
<li>もはやchromeにデフォルトエンコードというものはない。(たぶん)</li>
<li>何もエンコードに関する指定がない場合に採用されるのは、自動判別の結果(の内のどれか)である。判別できなかったらデフォルトエンコードになる、みたいな挙動ではない。(おそらく)</li>
<li>ぶっちゃけ、ちゃんとWEBサイトを作っていれば直面しない問題なので、わかってもあまり意味はない</li>
</ul>
<h2 id="とりあえず"><a href="#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A">とりあえず</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://chromium.googlesource.com/chromium/blink.git/+/master/Source">もぎゃさんの提示してくれたソース</a>を読もうと思ったんですけど……。<br />
なんだろう、これ。C++かな? 僕、C++やったことないんだよねえ……。<br />
これを機に覚えるというのも手ですが、正直そこまでの気力も時間もないし、機というほどのものでもないし、いきなりこのコードを読むのは辛いので、<strong>エンジニアらしからぬ感じで</strong>調べていこうと思います。</p>
<p>とりあえず、ソースを落としてきます。<br />
で、調べます。<br />
状況としては、「UTF-8になって欲しいものがShift_JISになってしまっている」ということなので、<strong>Shift_JISでgrepかけます。</strong><br />
馬鹿みたいで、期待薄ですが、とりあえずかけます。<br />
VSCodeとか駆使しても良いですが、C++の拡張とかよくわからないので原始的にいきます。</p>
<pre><code class="sh">$ grep -Ir Shift_JIS .
./platform/text/TextEncodingDetector.cpp: // a child frame in Shift_JIS and both frames do NOT specify the encoding
./wtf/text/TextCodecICU.cpp: registrar("shift-jis", "Shift_JIS");
</code></pre>
<p>……お?<br />
下のはshift-jisを正しくShift_JISにしている感じ? ちょっと関係なさそう。<br />
では、上のを見てみますか。TextEncodingDetectorなんて、いかにもそれっぽいじゃないですか。見るとなんか、コメントっぽいですね。</p>
<pre><code class="c"> // If no match is found so far, just pick the top match.
// This can happen, say, when a parent frame in EUC-JP refers to
// a child frame in Shift_JIS and both frames do NOT specify the encoding
// making us resort to auto-detection (when it IS turned on).
if (!encoding && matchesCount > 0)
encoding = ucsdet_getName(matches[0], &status);
</code></pre>
<p>とりあえずGoogle翻訳にかけます。<br />
<em>これまでに一致するものが見つからない場合は、一番上の一致を選択します。<br />
これは、たとえばEUC-JPの親フレームが<br />
Shift_JISの子フレームで、両方のフレームでエンコードが指定されていない<br />
自動検出機能がオンになっている場合。</em><br />
ふむふむ。たぶん、「一番上」ってのは</p>
<pre><code class="c">matches[0]
</code></pre>
<p>のことでしょう。では、matchesを入れてるのはというと、ちょい上に</p>
<pre><code class="c">const UCharsetMatch** matches = ucsdet_detectAll(detector, &matchesCount, &status);
</code></pre>
<p>おー。……なんでしょうucsdet_detectAllって?<br />
grepかけても出てこないので、何かのライブラリかな?<br />
ということでググります。</p>
<p>どうやら<a target="_blank" rel="nofollow noopener" href="https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/ucsdet_8h.html">ICU</a>というもので、<a target="_blank" rel="nofollow noopener" href="http://ykot.hateblo.jp/entry/20110112/1294821848">文字コード判定ができるもの</a>のようです。<br />
なんかそれっぽい。<br />
ただ、100%の精度ではないようで、複数の結果が返ってきたりすると。つまり、UTF-8だとかShift_JISだとかが配列になって返ってくるのかな。</p>
<p>で、</p>
<pre><code class="c">WTF::TextEncoding hintEncoding(hintEncodingName);
// (中略)
const char* matchEncoding = ucsdet_getName(matches[i], &status);
//(中略)
if (WTF::TextEncoding(matchEncoding) == hintEncoding) {
encoding = hintEncodingName;
break;
}
</code></pre>
<p>んー、hintEncodingは引数で受け取ったhintEncodingNameからゴニョゴニョした感じっぽい。<br />
こいつ自身は/core/html/parser/TextResourceDecoder.cppから呼ばれてるっぽいな。</p>
<pre><code class="c">if (detectTextEncoding(data, len, m_hintEncoding, &detectedEncoding))
setEncoding(detectedEncoding, EncodingFromContentSniffing);
</code></pre>
<p>それっぽい。</p>
<h2 id="そろそろ限界"><a href="#%E3%81%9D%E3%82%8D%E3%81%9D%E3%82%8D%E9%99%90%E7%95%8C">そろそろ限界</a></h2>
<p>そろそろ雰囲気だけで読むのは限界です……。<br />
何となく、metaタグやwebサーバーのレスポンスヘッダなどで指定されたエンコードと、ICUの判定結果を突合して一致したものをエンコードとしてるような気がする。<br />
で、一致しなかった場合、ICUの判定結果の0番目を採用する感じかな。<br />
これ以上は限界。</p>
<h2 id="遊んでみる"><a href="#%E9%81%8A%E3%82%93%E3%81%A7%E3%81%BF%E3%82%8B">遊んでみる</a></h2>
<p>こんなコードを書いてみます。で、いろんなエンコードで保存します。</p>
<pre><code class="html"><html>
<head>
</head>
<body>
てすと
<p id="charset"></p>
</body>
<script type="text/javascript">
document.getElementById('charset').innerText = document.characterSet
</script>
</html>
</code></pre>
<h3 id="UTF-8"><a href="#UTF-8">UTF-8</a></h3>
<p><a href="https://crieit.now.sh/upload_images/b4e7ccc0fa53a881f6b3b0f9843f0ac25efc2f0c6b0c3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b4e7ccc0fa53a881f6b3b0f9843f0ac25efc2f0c6b0c3.png?mw=700" alt="image" /></a><br />
たぶん、UTF-8もShift_JISも検出してるけど、Shift_JISの方が先って感じなのかな? アルファベット順かな?</p>
<h3 id="Shift_JIS"><a href="#Shift_JIS">Shift_JIS</a></h3>
<p><a href="https://crieit.now.sh/upload_images/1d242b199842e3f464b872ff003bdce95efc2f390b029.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1d242b199842e3f464b872ff003bdce95efc2f390b029.png?mw=700" alt="image" /></a><br />
なるほどそうなるよね</p>
<h3 id="EUC"><a href="#EUC">EUC</a></h3>
<p><a href="https://crieit.now.sh/upload_images/a10d542dd8e60570fefae9a2252b6bb25efc2f48bb917.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a10d542dd8e60570fefae9a2252b6bb25efc2f48bb917.png?mw=700" alt="image" /></a><br />
おっと? 一応表示されたけどGBKって何?<br />
と思ったら簡体字用のエンコードなのね。まさかの中国語判定。</p>
<h3 id="ちなみにutf-8のファイルをwebサーバー通さずにファイル表示すると"><a href="#%E3%81%A1%E3%81%AA%E3%81%BF%E3%81%AButf-8%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92web%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E9%80%9A%E3%81%95%E3%81%9A%E3%81%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E3%81%A8">ちなみにutf-8のファイルをwebサーバー通さずにファイル表示すると</a></h3>
<p><a href="https://crieit.now.sh/upload_images/0a6dd05da4378d2541e95beca5646ad15efc2f646522d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/0a6dd05da4378d2541e95beca5646ad15efc2f646522d.png?mw=700" alt="image" /></a><br />
なんで?<br />
きっとhintEncodingに何か入ってるんだろうけど……。確かに、ファイルを直で見れるので、Webサーバー通すより何かしらの情報はありそう。ただ、調べるにはちょっと力量の限界。</p>
<h2 id="その他"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96">その他</a></h2>
<p>前の記事のコメントで、apacheでは文字化けしてIISでは文字化けしなかったみたいなこと言いましたけど、改めて検証したらIISでもちゃんと?文字化けしました。(この調査結果だとそりゃそうなんですが)<br />
たぶん、何か環境構築とか検証方法を間違えてたんだと思いますが……。<br />
もちろん、nginxでも文字化けします。</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<ul>
<li>結論としては最初に言った通り</li>
<li>雑な考察なので信用に足るかは怪しい</li>
<li>わかる人は優しく教えてください</li>
<li>metaタグ等でエンコードはちゃんと設定しよう</li>
</ul>
hammhiko
tag:crieit.net,2005:PublicArticle/15622
2019-12-18T23:20:07+09:00
2019-12-19T13:06:45+09:00
https://crieit.net/posts/localhost
localhost監獄
<p>ここはlocalhost監獄。様々なwebアプリやスマホアプリが投獄されて日々を過ごしている。<br />
あなたはアプリを監獄(localhost)にぶち込んだ、検察官であり、裁判官であり、看守(アプリの開発者)である。<br />
今のあなたの仕事は、囚人(アプリ)を更生(完成)させ外の世界(インターネット)に旅立たせる(リリースする)ことだ。<br />
ところがこの囚人(アプリ)たち、なかなか厄介で、思った様に働いてくれない。<br />
彼らが日の目を浴びる日はいつくるのやら。</p>
<h2 id="さて"><a href="#%E3%81%95%E3%81%A6">さて</a></h2>
<p>crieitの<a href="https://crieit.net/advent-calendars/2019/crieit">なんでも Advent Calendar 2019</a>の18日目の記事です。ぎりぎりまだ18日です。<br />
前日はHataさんの<a href="https://crieit.net/posts/2019-5df9305f35c8a">プログラミングが好きでずっとプログラミングしていたい。2019</a>でした。<br />
ハートフルでなんかこう、好きなことに打ち込むっていいな、と思わせてくれる記事でした。<br />
そんな記事の翌日に、こんな意味のわからんポエムから始まる記事をぶっ込んで申し訳ない。懺悔します。<br />
(あと、たぶん、赤っぽいジャケットの長髪のカツラの人は彦じゃなくて、…きみま…)</p>
<h2 id="localhostになんかいる。いっぱい"><a href="#localhost%E3%81%AB%E3%81%AA%E3%82%93%E3%81%8B%E3%81%84%E3%82%8B%E3%80%82%E3%81%84%E3%81%A3%E3%81%B1%E3%81%84">localhostになんかいる。いっぱい</a></h2>
<p>さてさて。去年、<a target="_blank" rel="nofollow noopener" href="https://publn-s.xyz/">公共HP検索</a>というサイトを作って以来、実は色々とwebアプリを作ってきました。<br />
そいつらがみんな、<strong>ローカルホストで鎮座している。</strong><br />
上記のサイトですら閑古鳥が鳴く状態なのですが、それ以外は<strong>世に出てすらいない。</strong><br />
まあ、理由ははっきりしているんですけど。</p>
<h3 id="理由1.完成させようとしている"><a href="#%E7%90%86%E7%94%B11.%E5%AE%8C%E6%88%90%E3%81%95%E3%81%9B%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B">理由1.完成させようとしている</a></h3>
<p>個人開発の先人方はみんな言っていると思うので、今更なんですが。<br />
完成させようとしたらいつまでも完成しない。個人開発は締め切りがないのでパーキンソンの法則にしたがって、仕事量が無限に膨れ上がる。<br />
ある程度見切りをつけてリリースしないとダメ。<br />
わかってます。それでもリリースできないのは他にも理由があるからです。</p>
<h3 id="理由2.localhostで十分"><a href="#%E7%90%86%E7%94%B12.localhost%E3%81%A7%E5%8D%81%E5%88%86">理由2.localhostで十分</a></h3>
<p>これが結構マズい。<br />
そもそも、僕が何かを作る時って、<br />
<strong>こういうの欲しいな、どっかにないかな?→ないなー→よし、作るか!</strong><br />
こんな感じなので、一番の利用者は自分。自分が使うならlocalhostで十分ってなりがちです。出先で使いたいってなっても、最低限で作ってherokuやfirebaseにデプロイして、不安なら認証もかければ十分。<br />
そうやって完成度4割5割のアプリがどんどん増えていく。</p>
<p>とはいえ、作りかけのものを友達に見てもらうと(お世辞かもしれないけど)褒めてもらえるので、やっぱり他の人にも使ってもらいたいなという欲はあるんです。<br />
それでもリリースできないのは他にも理由が(ry</p>
<h3 id="理由3.個人開発に対する優先度が低い"><a href="#%E7%90%86%E7%94%B13.%E5%80%8B%E4%BA%BA%E9%96%8B%E7%99%BA%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E5%84%AA%E5%85%88%E5%BA%A6%E3%81%8C%E4%BD%8E%E3%81%84">理由3.個人開発に対する優先度が低い</a></h3>
<p>いや、割と致命的だよね。<br />
平日はフルタイムで働いて、定時後はジム行って汗流して、週末はクラブチーム所属でスポーツしてるんだもん。そりゃあ個人開発に時間取れないよねーって。<br />
(個人開発の話じゃないけど、完全に<a target="_blank" rel="nofollow noopener" href="https://hitodeblog.com/not-time-blog#i">これ</a>ですよね)<br />
まあ、そういう風に物事の優先度を設定しているのは他ならぬ自分なので、致し方ないというか。<br />
第一、みんな他にやることある中で、時間見つけて個人開発しているはずですから、条件一緒のはずなんですよね。</p>
<h2 id="それでも良くね?"><a href="#%E3%81%9D%E3%82%8C%E3%81%A7%E3%82%82%E8%89%AF%E3%81%8F%E3%81%AD%EF%BC%9F">それでも良くね?</a></h2>
<p>例えば、<br />
プロ野球選手が草野球をやっている人に対して「真面目にやれ!」と怒ることはないと思います。<br />
逆に、草野球の人がプロ野球を見てレベルの差を見て「自分が野球をやるなんておこがましい」と卑屈になる人もいないと思います。<br />
あたりまえですよね(たぶん)。</p>
<p>個人開発だって一緒で、いろんなスタンスの人がいるはずです。<br />
これを読んでいる人も「何を当たり前のことを」と思っていると思います。<br />
けど、twitterとかで個人開発にすごい熱量を注いでいる人を見ると、卑屈になってしまう自分がいて、その気持ちを落ち着かせるために文章にする必要があって、今書いているわけです。</p>
<p>結局のところ、自分が楽しいとか面白いとか思えればそれで良いのでは、って思ってます。<br />
(うまくいかないとか、辛いとかの試行錯誤とか諸々含めての「楽しい」)</p>
<blockquote>
<p>面白ければ良いんだ。面白ければ、無駄遣いではない。子供の砂遊びと同じだよ。面白くなかったら、誰が研究なんてするもんか。<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
</blockquote>
<div style="text-align:right">森博嗣「冷たい密室と博士たち」より</div>
<h2 id="とはいえ"><a href="#%E3%81%A8%E3%81%AF%E3%81%84%E3%81%88">とはいえ</a></h2>
<p>全然何も世の中に出さずにこんな事を語るのも居心地が悪いので、新しいwebアプリをリリースしようと思います。(小規模なやつだけど)<br />
本当はこの日に間に合わせるはずでしたが、色々諸事情でできなかったので、年末年始でリリースします。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://www.mobet.gq/jp/posts/5dfa31a7c3297b0009adf546">頑張ります</a></p>
<p>明日はshigeさんです!</p>
<div class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn:1" role="doc-endnote">
<p>ドラマ化したときにこのセリフが採用されなかったのが本当に納得できない。このシーンあったのに <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
hammhiko
tag:crieit.net,2005:PublicArticle/15594
2019-12-10T00:03:23+09:00
2019-12-10T00:03:23+09:00
https://crieit.net/posts/3d049d39c6ecdf05c4d92a0e4d4d7432
コンディションを保つために
<p><a href="https://crieit.net/advent-calendars/2019/non-coding-tips">プログラミング・コーディング以外のノウハウ・ティプス Advent Calendar 2019</a> の10日目の記事です。</p>
<p>ところで、プログラミング・コーディング以外のノウハウ・ティプスということでネタを考えたら、本当にプログラミング・コーディング以外の話になりそうだし、なんならプログラマとかクリエータとかもはや関係ない内容になりそうなんですが、誰に謝れば良いんでしょうか? だらさん? まんじゅさん?</p>
<p>と、そんなことばかり考えても先に進まないので、気にしないことにします。</p>
<h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2>
<p>さて、僕は常々コンディションというものを大事にしています。</p>
<p>先輩方には「若造が何を言っとるか」みたいに言われそうですけれど、<br />
* 二日酔いで極端にパフォーマンスが落ちる(以前より、という意味です)<br />
* なんなら6時間睡眠が2日続くだけでももうダメ(7時間は欲しい)<br />
* 筋肉痛が3日4日引かない(初日に来たうえでの2日目の追い討ち、からの治らない)<br />
* 風邪を引くと病院で薬をもらわないと治らない(昔は寝れば治ったのになあ……)<br />
* フィジカルとメンタルが密結合しだした(疲れるとすぐネガティブになる)</p>
<p>みたいなのを如実に感じるようになってきまして……。<br />
あと、メンタルボロクソになって働けなくなった経験もあるので、とにかく、フィジカル・メンタルのコンデイションにはそこそこ気を使っているわけです。<br />
とは言っても、基本方針としては、<br />
* <strong>食え</strong><br />
* <strong>寝ろ</strong><br />
* <strong>動け</strong></p>
<p>みたいな<del>脳筋</del><a target="_blank" rel="nofollow noopener" href="https://twitter.com/badassceo">筋トレ社長</a>が言いそうなことで、意見終了してしまうのですが……。<br />
ただ、これらってシンプルで全くもって正しいので、足りてないなと思ったら意識してやってみるようにしてください。<br />
特に運動。皆さん、ちゃんとやってます? 仕事で疲れてるのに運動なんてできない? <br />
それ、逆かもしれませんよ?<br />
「現代人の疲労の原因は運動不足」って話もありますから。</p>
<h2 id="ここから本題"><a href="#%E3%81%93%E3%81%93%E3%81%8B%E3%82%89%E6%9C%AC%E9%A1%8C">ここから本題</a></h2>
<p>これだけで終わってしまうと、「1+1は2です」くらいの情報しかないので、もう少し、雀の涙程度の情報は付加したいと思います。<br />
そうですね、<strong><em>ネガティブな状態を霧散させる方法</em></strong> とかどうでしょうか?</p>
<h3 id="前提条件"><a href="#%E5%89%8D%E6%8F%90%E6%9D%A1%E4%BB%B6">前提条件</a></h3>
<p>今回の「ネガティブな状態」とは、なんかダルい・無気力、みたいな<strong>慢性的な状態</strong>を指すこととします。<br />
漠然とした不安とか、原因はあるけどすぐには解決できないようなものとします。<br />
<del>(5000兆円欲しいけど、どう頑張っても手に入らない、悲しい。とか)</del></p>
<p>特定の事象に対する短期間なネガティブな感情にも使えないことはないですが、その原因を取り除く努力をした方が早いかもしれません。</p>
<h3 id="下準備"><a href="#%E4%B8%8B%E6%BA%96%E5%82%99">下準備</a></h3>
<p>手帳を買いましょう。<br />
別にアプリとかでも良いです。僕は電話中にスケジュールが確認できないのが嫌なので、物理で持ってますが。</p>
<h3 id="すること"><a href="#%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8">すること</a></h3>
<p>予定を入れましょう。詰め込みましょう。<br />
以上です。</p>
<h3 id="どういうこと?"><a href="#%E3%81%A9%E3%81%86%E3%81%84%E3%81%86%E3%81%93%E3%81%A8%EF%BC%9F">どういうこと?</a></h3>
<p>ネガティブな状態って、<strong>ネガティブな事を考える時間的余裕がある</strong>からこそ陥ってしまうと思うんですね。<br />
なので、スケジュールを入れて、考える時間をなくします。<del>脳筋です。</del></p>
<p>この手法自体は僕の経験談からくるものですが、同じような事を言っている人はいます。</p>
<p>例えば、オードリーの若林は「ネガティブを潰すのはポジティブではない。没頭だ。」と言ったとか言わないとか。<br />
<a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/完全版-社会人大学人見知り学部-卒業見込-角川文庫-若林/dp/4041026148">当該の本</a>を読んでいないので、詳細は分かりませんが、似たようなことではないかなと想像しています。</p>
<p>メンタリストDaiGoも<a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/B01BBW913M/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1">著書の一つ</a>でそんな感じの事を言っています。(正確にはカーネギーの著書の一部を紹介)</p>
<blockquote>
<p>医者から寝たきりになることを宣告されたこの女性は、事故から3カ月後は車椅子に乗って聴衆に向かって講演をしていました。その後も講演活動を精力的に続けて、大成功を収めたのです。<br />
(中略)<br />
頑張れた理由を聞かれて、彼女は「悲しんだり苦しんだりする暇をなくすためにそうした」と答えています。</p>
</blockquote>
<h3 id="FAQっぽい何か"><a href="#FAQ%E3%81%A3%E3%81%BD%E3%81%84%E4%BD%95%E3%81%8B">FAQっぽい何か</a></h3>
<p>Q. 入れる予定が思い浮かびません。<br />
A. なんでもよいと思います。<br />
「映画を見る」とか、「散歩をする」とか。<br />
「twitterをする」は個人的には避けた方が良いと思いますが。</p>
<p>Q. スケジュールを入れた結果、逆に疲れてしまいました。<br />
A. 予定の内容がまずいか、詰め込みすぎです。<br />
「予定=人と会う」みたいなイメージで、パリピのような予定を入れる必要はないです。多少、強制力のある予定があった方が良いとは思いますが。<br />
予定の詰め込みすぎで疲れるのは本末転倒なので、うまく調整してください。予定を詰め込むことが目的ではありません。<br />
何もしない時間はもちろんあって良いと思います。僕も意図的にそういう日を作ります。僕は「『何もしない』をする」と表現しています。</p>
<h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2>
<p>万人に通じる様なものではないと思いますが、誰かの役に立てば幸いです。</p>
hammhiko
tag:crieit.net,2005:PublicArticle/15566
2019-11-29T22:48:04+09:00
2019-11-29T22:48:04+09:00
https://crieit.net/posts/JavaScript
JavaScript:オブジェクトが中に入った配列をコピーする
<h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2>
<p>こんなの、絶対みんな直面していると思うんだけど、調べても出てこないのは、ググり方が悪いのか、需要がないのか、みんな余裕でやってしまうのか、なんなんだ?</p>
<h2 id="想定読者"><a href="#%E6%83%B3%E5%AE%9A%E8%AA%AD%E8%80%85">想定読者</a></h2>
<p>下記の挙動を理解している人</p>
<pre><code class="JavaScript">const array = [1,2,3];
const array2 = array;
console.log(array); // → [1,2,3]
array2[1] = 4;
console.log(array); // → [1,4,3]
</code></pre>
<h2 id="配列をディープコピーしたい"><a href="#%E9%85%8D%E5%88%97%E3%82%92%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%82%B3%E3%83%94%E3%83%BC%E3%81%97%E3%81%9F%E3%81%84">配列をディープコピーしたい</a></h2>
<p>配列をコピーして別物として扱いたいとき、 = で代入してはいけないのは流石に分かるのだけど、殊更JavaScriptになると「あれ、どうやるんだっけ?」と毎回調べるハメになる。<br />
しかも、やれ<a target="_blank" rel="nofollow noopener" href="https://qiita.com/takahiro_itazuri/items/882d019f1d8215d1cb67">sliceを使え、concatを使え</a>だの、やれ<a target="_blank" rel="nofollow noopener" href="https://pisuke-code.com/js-correct-way-of-array-copy/">Array.fromを使え</a>だの、様々な方法があって、かつ、そいつら、ディープコピーのメソッドじゃないよね? <a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/language.oop5.cloning.php">clone</a>とかないの?<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> という状況なのですが、文句を言っても仕方がないので、愚直にやるわけです。</p>
<h2 id="配列の中身がオブジェクトだとうまくいかない"><a href="#%E9%85%8D%E5%88%97%E3%81%AE%E4%B8%AD%E8%BA%AB%E3%81%8C%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%A0%E3%81%A8%E3%81%86%E3%81%BE%E3%81%8F%E3%81%84%E3%81%8B%E3%81%AA%E3%81%84">配列の中身がオブジェクトだとうまくいかない</a></h2>
<p>で、こんなコードを書いたわけですが、</p>
<pre><code class="JavaScript">const array = [{a:1},{a:2}];
const array2 = array.slice();
console.log(JSON.parse(JSON.stringify(array)));
// Array(2)
// 0: {a: 1}
// 1: {a: 2}
array2[1].a = 3;
console.log(JSON.parse(JSON.stringify(array)));
// ???
// Array(2)
// 0: {a: 1}
// 1: {a: 3}
</code></pre>
<p>目を疑った。あれ、実はsliceはダメなのかな? とか思ってconcatもArray.fromも試したけどダメ。<br />
1時間くらい悩んで、「ああ、配列はディープコピーされたけど、中のオブジェクトが参照のままなのか」と気がついた。</p>
<pre><code class="JavaScript">const array = [{a:1},{a:2}];
const array2 = array.slice();
console.log(JSON.parse(JSON.stringify(array)));
// Array(2)
// 0: {a: 1}
// 1: {a: 2}
array2.push({a:3});
console.log(JSON.parse(JSON.stringify(array)));
// 配列はディープコピーされている
// Array(2)
// 0: {a: 1}
// 1: {a: 2}
console.log(JSON.parse(JSON.stringify(array2)));
// Array(3)
// 0: {a: 1}
// 1: {a: 2}
// 2: {a: 3}
</code></pre>
<h2 id="解決策"><a href="#%E8%A7%A3%E6%B1%BA%E7%AD%96">解決策</a></h2>
<p>え、これどーすんの? と少し悩んで、下記の様にした。</p>
<pre><code class="JavaScript">const array = [{a:1},{a:2}];
const array2 = array.map((obj) => Object.assign({},obj));
console.log(JSON.parse(JSON.stringify(array)));
// Array(2)
// 0: {a: 1}
// 1: {a: 2}
array2.push({a:3});
console.log(JSON.parse(JSON.stringify(array)));
// 配列はOK
// Array(2)
// 0: {a: 1}
// 1: {a: 2}
array2[1].a = 4;
console.log(JSON.parse(JSON.stringify(array)));
// 中のオブジェクトもディープコピーしている
// Array(2)
// 0: {a: 1}
// 1: {a: 2}
console.log(JSON.parse(JSON.stringify(array2)));
// Array(3)
// 0: {a: 1}
// 1: {a: 4}
// 2: {a: 3}
</code></pre>
<p>Array.map()の中でオブジェクトをObject.assign()でディープコピーして返している。mapは新しい配列を返すので、配列のコピーもOK。</p>
<h2 id="ところで、オブジェクトのディープコピーって"><a href="#%E3%81%A8%E3%81%93%E3%82%8D%E3%81%A7%E3%80%81%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%82%B3%E3%83%94%E3%83%BC%E3%81%A3%E3%81%A6">ところで、オブジェクトのディープコピーって</a></h2>
<p>オブジェクトのディープコピーも調べるといくつか出てくる。<br />
<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Examples">Object.assign</a>ってのがあるんだけど、<a target="_blank" rel="nofollow noopener" href="https://kuroeveryday.blogspot.com/2017/05/deep-clone-object-in-javascript.html">Object.assignはシャローコピーなのでJSON.parse/JSON.stringify</a>って人もいれば、<a target="_blank" rel="nofollow noopener" href="https://qiita.com/seihmd/items/74fa9792d05278a2e898">JSON.parse/JSON.stringifyは安易に使うな</a>、<a target="_blank" rel="nofollow noopener" href="https://qiita.com/seihmd/items/74fa9792d05278a2e898#comment-7b97f37d119fb69712f2">Object.assignがディープコピーだからそっちを使え</a>っていう堂々巡りで、というか読んでいるとどっちもどっち感が強くて、状況に合わせて自力でどうにかするしかないじゃんっていう……。</p>
<h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2>
<p>もっと正しいスマートなやり方を教えてください。</p>
<div class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn:1" role="doc-endnote">
<p>phpのcloneが配列に使えない(そして使う必要がない)のは知っているのだけれど、良い例が思い浮かばなかったのです。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
hammhiko
tag:crieit.net,2005:PublicArticle/15521
2019-10-31T08:02:37+09:00
2019-10-31T08:02:37+09:00
https://crieit.net/posts/Vue-Buefy
Vue + Buefyでサーバーからファイルを受け取ってファイルアップロードにセットする
<p>そんな需要がどこにあるのか知らんが。</p>
<h2 id="動作環境"><a href="#%E5%8B%95%E4%BD%9C%E7%92%B0%E5%A2%83">動作環境</a></h2>
<p>OS: macOS High Sierra 10.13.6<br />
ブラウザ: Chrome 77.0.3865.90<br />
vue: 2.6.10<br />
buefy: 0.8.4</p>
<h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2>
<p>やりたいこととしては、タイトルの通りです。</p>
<p>需要があるとは到底思えないのだけれど、思いついてやってみたらそれっぽくできてしまったので。</p>
<p><del>無理やり使う場面を考えるとすると、例えば電子申請伝票に添付ファイルを(領収証とかをpdfで)つけたいのだけど、申請前に一時保存する機能をつけたい。保存時に添付ファイルはサーバーに送られるのだけど、再編集時にファイルアップロードにセットしたい、とか。でもそんな業務チックなシステムをvue + buefyでやるとは思えないので、やっぱり使う場面が思い浮かばない。</del></p>
<h2 id="普通のファイルアップロードだと無理"><a href="#%E6%99%AE%E9%80%9A%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A0%E3%81%A8%E7%84%A1%E7%90%86">普通のファイルアップロードだと無理</a></h2>
<p>普通のファイルアップロード(input type="file")だと<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/HTML/Element/Input/file#Using_file_inputs">セキュリティ上の理由で無理</a>。まあ、<a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/1696877/how-to-set-a-value-to-a-file-input-in-html/1696884#1696884">そうだよな</a>って感じではありますが。<br />
別に、valueに端末のパスを指定して悪さしたいわけじゃなくて、直にfiles[0]にFileオブジェクトを突っ込んでおきたいのだけど。。。</p>
<h2 id="Buefyならなんとか"><a href="#Buefy%E3%81%AA%E3%82%89%E3%81%AA%E3%82%93%E3%81%A8%E3%81%8B">Buefyならなんとか</a></h2>
<p>Buefyのb-uploadなら、VueのdataにFileオブジェクトを保持して、擬似的(?)にファイルアップロードを作っているっぽいのでできそうです。<br />
やる場面があるか知らんが。</p>
<p>要は、VueのdataにFileオブジェクトを突っ込めれば良いので、サーバーからのファイルのデータをFileオブジェクトに変換するというのがメインの作業になります。</p>
<p><del>面倒なので</del><a href="https://crieit.net/posts/Vue-Buefy-onChange">前回</a>のソースに手を加える感じにします。</p>
<p>と、その前にサーバー側。<br />
よしなにやれば良いと思いますが、今回は簡単にLaravel使ってこんな感じでStorageでgetして返してます。</p>
<pre><code class="php">return Storage::get('PUBLN-S-logo.png');
</code></pre>
<p>でフロント側</p>
<pre><code class="HTML"><template>
<div>
<b-field class="file">
<b-upload v-model="file">
<a class="button is-primary">
<b-icon icon="upload"></b-icon>
<span>Click to upload</span>
</a>
</b-upload>
<span class="file-name" v-if="file">
<span>{</span><span>{</span> file.name <span>}</span><span>}</span>
</span>
</b-field>
<!-- サーバーから取得するボタンを追加 -->
<b-button type="is-info" @click="getFile">サーバーから取得</b-button>
<img :src="image" />
</div>
</template>
<script>
export default {
data:function(){
return {
file:null
}
},
computed:{
image:function(){
return this.file ? window.URL.createObjectURL(this.file) : ""
}
},
// サーバーからファイルを取得するメソッドを追加
methods:{
getFile:async function(){
const response = await fetch('/api/getFile')
if(response.ok){
const blob = await response.blob()
this.file = new File([blob],'PUBLN-S-logo.png')
}
}
}
}
</script>
</code></pre>
<p>fetchだとレスポンスをblobをブジェクトに変換するblobメソッドがあるので、それを使います。<br />
blobだとb-uploadが受け付けないのでFileオブジェクトにする必要がありますが、コンストラクタでblobを渡すことができるので、難しくありません。<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/API/File/File">配列で渡す必要があるのをうっかりしそうですが。</a></p>
<p><a href="https://crieit.now.sh/upload_images/ee8d5bfe911060c36b5051bfff42b5d25db2b970e38d6.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ee8d5bfe911060c36b5051bfff42b5d25db2b970e38d6.png?mw=700" alt="ボタン押す前.png" /></a><br />
ボタンを押すと<br />
<a href="https://crieit.now.sh/upload_images/d73deec111f32c40e2f7e0bbdd5f81845db2b98570303.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d73deec111f32c40e2f7e0bbdd5f81845db2b98570303.png?mw=700" alt="ボタン押した後.png" /></a><br />
サーバーから取ってきてセット(ついでにプレビュー)</p>
<h2 id="終わりに"><a href="#%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%AB">終わりに</a></h2>
<p>細かいところは検証してないですが、とりあえず動いたので。<br />
たぶん、色々セキュリティとかも含めちゃんとしなきゃいけないとは思います。<br />
そもそも使いどころはわかりませんが。</p>
hammhiko
tag:crieit.net,2005:PublicArticle/15514
2019-10-28T22:45:05+09:00
2019-10-28T22:45:05+09:00
https://crieit.net/posts/FTP
FTPコマンドは半端な入力を補完して実行してくれる?
<h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2>
<p>/^[^S]*FTP[^S]*$/の話なので、他はわからないし、今さら使うこともないのでは、と思わないでもないですが。<br />
FTPであることについては、言いたいことを全て飲み込んでください。お願いします。</p>
<p>あ、あと環境。<br />
OS: macOS High Sierra 10.13.6<br />
ftp: 1.9.4</p>
<h2 id="発端"><a href="#%E7%99%BA%E7%AB%AF">発端</a></h2>
<p>僕ってしょっちゅう<a target="_blank" rel="nofollow noopener" href="https://qiita.com/gm_kou/items/2840a6670dc2e733d00a">sl</a>コマンドだとか<a target="_blank" rel="nofollow noopener" href="https://qiita.com/esplo/items/d87324077a93d405cad6">dc</a>コマンドを実行してしまうんですが、そんな感じでこの間も</p>
<pre><code class="sh">$ ftp
ftp> passiv
</code></pre>
<p>こんな感じでeが<del>押ささんなくて</del>押せなくてEnterしちゃったんですね。<br />
そしたら、</p>
<pre><code class="sh">$ ftp
ftp> passiv
Passive mode on.
ftp>
</code></pre>
<p>ちょっと目を疑った。俺、ちゃんと打ててないよ?<br />
で、ちょっと試してみた。</p>
<pre><code class="sh">$ ftp
ftp> passive
Passive mode on.
ftp> passiv
Passive mode off.
ftp> passi
Passive mode on.
ftp> pass
Passive mode off.
ftp> pas
Passive mode on.
ftp> pa
Passive mode off.
ftp> p
?Ambiguous command
</code></pre>
<p>まじかー。<br />
Invalid じゃなくて Ambiguous なあたり、<br />
これってコマンドの候補が一つに確定したら途中でも実行してくれるってことかなー。つーことはpがダメなのはputがあるからかー。<br />
と想像した。</p>
<p>ということで、</p>
<pre><code class="sh">$ ftp
ftp> ope
(to)
</code></pre>
<p>なるほどこうなるよなー。</p>
<h2 id="みんな知ってんの?"><a href="#%E3%81%BF%E3%82%93%E3%81%AA%E7%9F%A5%E3%81%A3%E3%81%A6%E3%82%93%E3%81%AE%EF%BC%9F">みんな知ってんの?</a></h2>
<p>これって常識なのかな? と疑って隣の人に聞いてみたら、知らなかった。少なくとも自分だけではなかった。<br />
軽くググってみた。<br />
けど、<br />
<em>ftp 補完</em><br />
とかだとファイル名のTab補完の話になるし、<br />
<em>ftp コマンド 途中</em><br />
とかだと通信が途中で切れた場合の挙動の話になるし、<br />
調べ方がよくわからなかった。<br />
うーん。</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>確定しているし、間違った実行とかはないだろうけど、一応、普通に打った方が良いと思う。</p>
hammhiko
tag:crieit.net,2005:PublicArticle/15450
2019-10-04T08:03:30+09:00
2019-10-04T08:03:30+09:00
https://crieit.net/posts/Vue-Buefy-onChange
Vue + Buefy で画像ファイルのプレビューを実装しようとしたらonChangeが効かなくて少しだけ困った話
<p>まあ、自分のやろうとしたことが、正攻法じゃなかっただけかもしれないけど。</p>
<h2 id="動作環境"><a href="#%E5%8B%95%E4%BD%9C%E7%92%B0%E5%A2%83">動作環境</a></h2>
<p>まずは、一応<br />
OS: macOS High Sierra 10.13.6<br />
ブラウザ: Chrome 77.0.3865.90<br />
vue: 2.6.10<br />
buefy: 0.8.4</p>
<h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2>
<p>vue + buefy でwebサイトを作っていて、画像ファイルのアップロードとプレビューを実装しようと思った。<br />
それ自体は調べれば色々出てくるので難しいものではなかった。(ちょっと疑問は残ったけど<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>)</p>
<p>だいぶ雑に書くけど</p>
<pre><code class="html"><template>
<div>
<input type="file" @change="changeImage"/></br>
<img :src="image" />
</div>
</template>
<script>
export default {
data:function(){
return {
image:"",
}
},
methods:{
changeImage:function(e){
const file = e.target.files[0]
if(file){
this.image = window.URL.createObjectURL(file)
}
else{
this.image = ""
}
}
}
}
</script>
</code></pre>
<p>こんな感じでできる。<br />
(ほんとは、ファイルがないときはimgタグ隠すとか、fileは画像ファイルだけ受け付けるとか色々必要だけど)<br />
<a href="https://crieit.now.sh/upload_images/a334b71dd1b2092bcb878ad39886cb0b5d959623f0738.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a334b71dd1b2092bcb878ad39886cb0b5d959623f0738.png?mw=700" alt="input_選択前.png" /></a><br />
<a href="https://crieit.now.sh/upload_images/839748f460ee8aa0e4ba5e0c6855668b5d959636858d7.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/839748f460ee8aa0e4ba5e0c6855668b5d959636858d7.png?mw=700" alt="input_選択後.png" /></a></p>
<p>ところがこれを</p>
<pre><code class="html"><template>
<div>
<b-input type="file" @change="changeImage"></b-input></br>
<img :src="image" />
</div>
</template>
<script>
export default {
data:function(){
return {
image:"",
}
},
methods:{
changeImage:function(e){
const file = e.target.files[0]
if(file){
this.image = window.URL.createObjectURL(file)
}
else{
this.image = ""
}
}
}
}
</script>
</code></pre>
<p>buefyのb-inputに変更したら途端に動かなくなった。<br />
どうもonChangeが発火していないみたい。</p>
<p><a href="https://crieit.now.sh/upload_images/7d99cb8f10de2099da56aaf7f4fc7a615d95964c9582d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7d99cb8f10de2099da56aaf7f4fc7a615d95964c9582d.png?mw=700" alt="b-input_選択前.png" /></a><br />
<a href="https://crieit.now.sh/upload_images/48f566844156ce0351ddfc4edba1f50c5d95965866f6a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/48f566844156ce0351ddfc4edba1f50c5d95965866f6a.png?mw=700" alt="b-input_選択後.png" /></a></p>
<h2 id="解決策"><a href="#%E8%A7%A3%E6%B1%BA%E7%AD%96">解決策</a></h2>
<p>原因がはっきりしないのだけど、(というか調べていない)とりあえずなんとかする方法はある。</p>
<h3 id="1. b-inputをやめる"><a href="#1.+b-input%E3%82%92%E3%82%84%E3%82%81%E3%82%8B">1. b-inputをやめる</a></h3>
<p>そもそも、元々動いていたのだから素直にinputを使う。で、bulmaなり素のcssでデザインをなんとかすれば良い。</p>
<h3 id="2. b-inputではなくb-uploadを使う"><a href="#2.+b-input%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%8Fb-upload%E3%82%92%E4%BD%BF%E3%81%86">2. b-inputではなくb-uploadを使う</a></h3>
<p>こっちの方が正攻法のような気がする。<br />
そもそもbuefyにはb-input以外に、アップロード用のコンポーネントb-uploadがある。<br />
(正体は input type="file" っぽいけど)<br />
こっちだとv-modelでfileオブジェクトをバインドできるので、onChangeイベントも要らず算出プロパティでできたりする。<br />
※ちなみにinputでv-modelを使おうとすると、type="file"の場合、vueのエラーになる。b-uploadも最終的にはinputになるのに、何故……?</p>
<pre><code class="html"><template>
<div>
<b-field class="file">
<b-upload v-model="file">
<a class="button is-primary">
<b-icon icon="upload"></b-icon>
<span>Click to upload</span>
</a>
</b-upload>
<span class="file-name" v-if="file">
<span>{</span><span>{</span> file.name <span>}</span><span>}</span>
</span>
</b-field>
<img :src="image" />
</div>
</template>
<script>
export default {
data:function(){
return {
file:null
}
},
computed:{
image:function(){
return this.file ? window.URL.createObjectURL(this.file) : ""
}
}
}
</script>
</code></pre>
<p><a href="https://crieit.now.sh/upload_images/f7e91aa39348cc0c35490d9169a1fadb5d959a875dc2e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f7e91aa39348cc0c35490d9169a1fadb5d959a875dc2e.png?mw=700" alt="b-upload_選択前.png" /></a><br />
(雑にやったせいかアイコンが出てないけど……)<br />
<a href="https://crieit.now.sh/upload_images/f6bf7fd4c8a99b234c2ec464f45251095d959a94d6819.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f6bf7fd4c8a99b234c2ec464f45251095d959a94d6819.png?mw=700" alt="b-upload_選択後.png" /></a></p>
<h3 id="番外編 b-inputでv-modelを使う(ダメでした)"><a href="#%E7%95%AA%E5%A4%96%E7%B7%A8+b-input%E3%81%A7v-model%E3%82%92%E4%BD%BF%E3%81%86%EF%BC%88%E3%83%80%E3%83%A1%E3%81%A7%E3%81%97%E3%81%9F%EF%BC%89">番外編 b-inputでv-modelを使う(ダメでした)</a></h3>
<p>この記事を書いていて、「あれ? 最終的にinputになるb-uploadがv-model使えるのなら、b-inputのtype="file"でもv-model使えるんじゃね?」って思ってやってみたけどダメだった。<br />
vue側ではエラーにならないけど、バインドされるのがFileオブジェクトではなくファイルパスの文字列だった。<br />
b-uploadはコンポーネントの中で色々よしなに頑張ってくれているんだろうなあ。</p>
<h2 id="終わりに"><a href="#%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%AB">終わりに</a></h2>
<p>個人的には、いかにも「ファイルアップロードです!」みたいな見た目が嫌いではないし、対応としてはどっちでも良いと思うのだけれど、まあ、状況に合わせて対応すれば良いと思う。</p>
<div class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn:1" role="doc-endnote">
<p>みんなonChangeでFileオブジェクト取得してFileReaderでonloadしてreadAsDataURLでimgのsrcに入れてるんだけど、今回やってるみたいにFileオブジェクトからwindow.URL.createObjectURLじゃダメなの? <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
hammhiko
tag:crieit.net,2005:PublicArticle/15361
2019-08-28T22:16:53+09:00
2019-08-28T22:16:53+09:00
https://crieit.net/posts/286dbb98a2515d93ed8e7d9fa4746b45
何も考えず手癖で書いたり、眠いなーって思いながら書いた、なんかパッとしないコードたち
<h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2>
<p>とりあえずググろう。特にPHPは関数が充実してるから、なにかしらある。<br />
という自分への戒め。<br />
beforeがパッとしないコードたち、それを改善したのがafter。</p>
<h2 id="配列Aのi番目と配列Bのi番目を同時に操作したい"><a href="#%E9%85%8D%E5%88%97A%E3%81%AEi%E7%95%AA%E7%9B%AE%E3%81%A8%E9%85%8D%E5%88%97B%E3%81%AEi%E7%95%AA%E7%9B%AE%E3%82%92%E5%90%8C%E6%99%82%E3%81%AB%E6%93%8D%E4%BD%9C%E3%81%97%E3%81%9F%E3%81%84">配列Aのi番目と配列Bのi番目を同時に操作したい</a></h2>
<p>初心者の頃から時が止まっていた。<br />
言語:PHP<br />
参考:<a target="_blank" rel="nofollow noopener" href="https://qiita.com/KOH_TA/items/c69b0fce9da1b114fef9">【PHP】複数の配列を同時に while で回す</a></p>
<p>before</p>
<pre><code class="php">$arrayA = ['a', 'b', 'c'];
$arrayB = ['1', '2', '3'];
$count = count($arrayA);
for ($i = 0; $i < $count; ++$i) {
$a = $arrayA[$i];
$b = $arrayB[$i];
hoge($a, $b); // aとbでなんかする
}
</code></pre>
<p>after</p>
<pre><code class="php">$arrayA = ['a', 'b', 'c'];
$arrayB = ['1', '2', '3'];
foreach (array_map(null, $arrayA, $arrayB) as [$a, $b]) {
hoge($a, $b); // aとbでなんかする
}
</code></pre>
<h2 id="CSVをN件ずつバルクインサートorマルチプルインサートしたい"><a href="#CSV%E3%82%92N%E4%BB%B6%E3%81%9A%E3%81%A4%E3%83%90%E3%83%AB%E3%82%AF%E3%82%A4%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%88or%E3%83%9E%E3%83%AB%E3%83%81%E3%83%97%E3%83%AB%E3%82%A4%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%88%E3%81%97%E3%81%9F%E3%81%84">CSVをN件ずつバルクインサートorマルチプルインサートしたい</a></h2>
<p>こんなクソダサい実装嫌だとか思ってたけど、クソ眠くて何も思い浮かばなかった。<br />
言語:PHP<br />
参考:<a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.array-chunk.php">array_chunk</a></p>
<p>before</p>
<pre><code class="php">$csv = hoge(); // SplFileObjectとかでCSVファイルを配列に
$records = [];
$arrayByInsertUnit = [];
foreach ($csv as $row) {
// 空行の処理は本題と逸れるので省略
$records[] = ['cd' => $row[0], 'name' => $row[1]];
if (count($records) === 1000) {
$arrayByInsertUnit[] = $records;
$records = [];
}
}
// 余り
$arrayByInsertUnit[] = $records;
foreach ($arrayByInsertUnit as $unit) {
//トランザクションとかは割愛
Model::insert($unit); // LaravelとかのORMとかでインサート
}
</code></pre>
<p>after</p>
<pre><code class="php">$csv = hoge(); // SplFileObjectとかでCSVファイルを配列に
$records = [];
foreach ($csv as $row) {
// 空行の処理は本題と逸れるので省略
$records[] = ['cd' => $row[0], 'name' => $row[1]];
}
$arrayByInsertUnit = array_chunk($records, 1000);
foreach ($arrayByInsertUnit as $unit) {
//トランザクションとかは割愛
Model::insert($unit); // LaravelとかのORMとかでインサート
}
</code></pre>
<p>あれ、でも、これ、綺麗にはなったけど、一度配列に全部入れてから分割してるから、beforeより遅い??</p>
<p>それと、insertのところ、laravelでやろうとするとバルクなの? マルチプルなの?</p>
<h2 id="取得したDOMをループで回したい"><a href="#%E5%8F%96%E5%BE%97%E3%81%97%E3%81%9FDOM%E3%82%92%E3%83%AB%E3%83%BC%E3%83%97%E3%81%A7%E5%9B%9E%E3%81%97%E3%81%9F%E3%81%84">取得したDOMをループで回したい</a></h2>
<p>手癖とか眠いとか関係なく普通に知らなかった。JavaScript難しい<br />
言語:JavaScript<br />
参考:<a href="https://crieit.net/boards/programming-challenge/8fee498e810148d4d4cc59e8631c01eb#comments">Crieit プログラミングチャレンジ</a></p>
<p>before<br />
最初、普通にforEachしようとしたらエラーになったので、仕方なくforにしてた。</p>
<pre><code class="JavaScript">const li = document.getElementsByTagName("li");
const count = li.length;
for (let i = 0; i < count; i++) {
const val = li[i].value;
hoge(val); // なんかする
}
</code></pre>
<p>after</p>
<pre><code class="JavaScript">Array.from(document.getElementsByTagName("li")).forEach(li => {
const val = li.value;
hoge(val); // なんかする
});
</code></pre>
<p>forEachよりmapとかfilterとかの方が多いと思うけど、たぶん一緒。</p>
<h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2>
<p>何か思いつけばまた生き恥を晒すかもしれない</p>
hammhiko
tag:crieit.net,2005:PublicArticle/15228
2019-07-12T19:35:42+09:00
2019-07-12T19:35:42+09:00
https://crieit.net/posts/apache-configtest-Syntax-OK
apacheのconfigtestは"Syntax OK"でもエラー扱い
<h2 id="最初に。ごめんなさい"><a href="#%E6%9C%80%E5%88%9D%E3%81%AB%E3%80%82%E3%81%94%E3%82%81%E3%82%93%E3%81%AA%E3%81%95%E3%81%84">最初に。ごめんなさい</a></h2>
<p>タイトル盛りました。<br />
正確には、<br />
<strong>apacheのconfigtestは"Syntax OK" を標準エラー出力する。戻り値はちゃんと0が返る。</strong><br />
です。</p>
<p>調べてもあまり情報出てこなかったし、誰も気にしていないんだろうけど。</p>
<h2 id="確認したバージョン"><a href="#%E7%A2%BA%E8%AA%8D%E3%81%97%E3%81%9F%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3">確認したバージョン</a></h2>
<pre><code>Server version: Apache/2.2.34 (Unix)
</code></pre>
<pre><code>Server version: Apache/2.4.33 (Unix)
</code></pre>
<h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2>
<p>定期的に(結構な頻度で)apacheのエイリアスを増やさなきゃいけない不思議な環境がありまして。<br />
いい加減、手作業がダルいので、シェルで自動化しようと考えまして。</p>
<pre><code class="sh"># 色々処理をごにょごにょ
doSomething1
doSomething2
doSomething...
service httpd configtest >> logfile
RET=$?
echo $RET >> logfile
if [ ${RET} = 0 ]; then
service httpd graceful
fi
</code></pre>
<p>(今、そらで書いたのでだいぶ怪しい)</p>
<p>で、動かして見たらconfigtestのところがログになかった。<br />
あれ???ってなって、構文ミスったかな? とか、いろいろ見直した。<br />
最終的にやっと気が付いて、</p>
<pre><code class="sh"># 色々処理をごにょごにょ
doSomething
doSomething2
doSomething...
service httpd configtest >> logfile 2>&1
RET=$?
echo $RET >> logfile
if [ ${RET} = 0 ]; then
service httpd graceful
fi
</code></pre>
<p>これでちゃんとログに出た。</p>
<h2 id="ちょっと待って"><a href="#%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E5%BE%85%E3%81%A3%E3%81%A6">ちょっと待って</a></h2>
<p>Q. これってapacheの仕様うんぬんの前に……。<br />
A. はい。何らかのエラー出力があった場合もログに出ないので、最初のプログラムはただの僕が作ったバグです。</p>
<h2 id="まあ"><a href="#%E3%81%BE%E3%81%82">まあ</a></h2>
<p>戻り値はちゃんと出し分けてるのに(当たり前だ)<br />
出力は出し分けずに標準エラー出力で統一ってのも、なんか不思議な気はする。<br />
まあ、だいたい2>&1するし、実害はないんだけど。</p>
hammhiko
tag:crieit.net,2005:PublicArticle/15170
2019-06-26T23:27:43+09:00
2019-06-26T23:27:43+09:00
https://crieit.net/posts/93f83330f40486b5dac68481418798e8
ハッカーな気分
<h2 id="今は昔"><a href="#%E4%BB%8A%E3%81%AF%E6%98%94">今は昔</a></h2>
<p>むかーしむかし、僕がまだ、小学生とか中学生とか、とにかく、パソコンとかプログラムとかよくわかっていなかった頃の話だ。<br />
アニメやドラマ、映画を見ていると、たまにハッカーみたいなやつが出てくることがある。それは時にはハッカーだし、時にはクラッカーだったりするのだけれど、今はとりあえず、どちらでも良い。<br />
とにかくだ。彼らはすごいのだ。<br />
何がすごいって、ダダダダダッってキーボードを淀みなく叩き続けて、画面には理解不能な文字列がバババババッって表示されて、ッターンって仕上げにキーボードを叩くと、何かすげーことが起きる。<br />
何か、すげーのだ。<br />
別に憧れたりはしなかったけど。</p>
<h2 id="少し昔"><a href="#%E5%B0%91%E3%81%97%E6%98%94">少し昔</a></h2>
<p>とか言いながら、僕は新卒でSIerの企業に入った。<br />
扱ったのは、Windows Server で動くC#製のWebアプリだ。</p>
<p>Windows Server ってGUIだから普段のPCの延長みたいなものだし、普段の開発もだいたい手はそんなに動かない。悩んで調べて動かなくて……。<br />
おおよそ手はキーボードの上じゃなくて、マウスの上か頭の上(頭抱えてる)にある。時々キーボードって感じだ。<br />
昔見たハッカーはやっぱりフィクションなんだなーと、ふと思ったりした。<br />
別に憧れて入った訳じゃないから、何も問題ないのだけれど。</p>
<h2 id="ちょっと前"><a href="#%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E5%89%8D">ちょっと前</a></h2>
<p>転職した。その話は今は関係ないので省く。<br />
扱うものがWindowsからLinuxに変わった。<br />
最初はCUIがすげー辛かった。ファイルを探そうにもエクスプローラすらないのだもの。<br />
最初はTab補完すら知らなくて、ファイル探すだけでこんな大変だなんて、どうかしてる、とさえ思ったりした。<br />
そのうち慣れていったけど。</p>
<h2 id="ある時"><a href="#%E3%81%82%E3%82%8B%E6%99%82">ある時</a></h2>
<p>自分が、ダダダダダッってキーボードを淀みなく叩き続けて、コンソールに文字列をバババババッって表示させているのに気が付いた。</p>
<p>あ、ちょっとハッカーっぽい。</p>
<p>少し思って、すごく虚しくなった。</p>
<p>だって。</p>
<p>cdとlsを打ち続けて、ログを見つけてgrepかけただけだもの。<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<div class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn:1" role="doc-endnote">
<p>「エクスプローラをポチポチクリックして、サクラエディタのgrep機能でログを検索する」とwindowsに置き換えて書いてみると虚しさが倍増する。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
hammhiko
tag:crieit.net,2005:PublicArticle/15157
2019-06-24T00:26:52+09:00
2019-06-24T00:26:52+09:00
https://crieit.net/posts/862e62c7911e527564fa9231fb64a4f9
参照の値渡しがわからなかったのだけれども
<p>ちょっと前に、参照渡しが盛り上がりましたね。<br />
参照渡しというか、参照の値渡しがどうもしっくりこなくて。</p>
<p>ちょっとPHPで書いてみます。</p>
<h2 id="①オブジェクトを渡してプロパティを変える"><a href="#%E2%91%A0%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E6%B8%A1%E3%81%97%E3%81%A6%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%92%E5%A4%89%E3%81%88%E3%82%8B">①オブジェクトを渡してプロパティを変える</a></h2>
<p>これを最初に見た時の感想は、<br />
「プロパティが変わってる! そうか、これは参照渡しなんだ!」では<strong>断じてなくて</strong>、<br />
「なんで値渡しなのに関数の外で変わってんだよ!」だったのですが。</p>
<pre><code class="php">$a = new stdClass();
$a->hoge = 5;
$a->fuga = 10;
var_dump($a);
func($a);
var_dump($a);
function func($a){
$a->hoge = 6;
}
</code></pre>
<pre><code class="php">class stdClass#1 (2) {
public $hoge =>
int(5)
public $fuga =>
int(10)
}
class stdClass#1 (2) {
public $hoge =>
int(6)
public $fuga =>
int(10)
}
</code></pre>
<h2 id="②オブジェクトを渡してオブジェクトごと変える"><a href="#%E2%91%A1%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E6%B8%A1%E3%81%97%E3%81%A6%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%94%E3%81%A8%E5%A4%89%E3%81%88%E3%82%8B">②オブジェクトを渡してオブジェクトごと変える</a></h2>
<pre><code class="php">$a = new stdClass();
$a->hoge = 5;
$a->fuga = 10;
var_dump($a);
func($a);
var_dump($a);
function func($a){
$a = new stdClass();
$a->hoge = 6;
$a->fuga = 11;
}
</code></pre>
<pre><code class="php">class stdClass#1 (2) {
public $hoge =>
int(5)
public $fuga =>
int(10)
}
class stdClass#1 (2) {
public $hoge =>
int(5)
public $fuga =>
int(10)
}
</code></pre>
<p>むしろこれが普通だろ、値渡しなんだから。と思っていたけど、そうすると、なんで①は変わってしまうの??? って状態だった。</p>
<h2 id="参照の値渡し"><a href="#%E5%8F%82%E7%85%A7%E3%81%AE%E5%80%A4%E6%B8%A1%E3%81%97">参照の値渡し</a></h2>
<p>色々な記事をみて、「参照渡し」と、「参照の値渡し」というのがあるってのはわかって、なんとなく、ぼやーっとはわかったような、わからないような。</p>
<p>②が普通だと思っていたのに、①を見てから②を見ると、なんか変というか、<br />
まるで、newした瞬間に何かが起こったような、突然変異でも起きたの? みたいなもやもやがあった。<br />
けど、下のコードを思い至って、少しスッキリした。<br />
とどのつまり、実際、結局、newした瞬間に何かが起こったわけだ。<br />
参照値が変わった、ということなのかな?</p>
<pre><code class="php">$a = new stdClass();
$a->hoge = 5;
$a->fuga = 10;
var_dump($a);
func($a);
var_dump($a);
function func($a){
$a->hoge = 0;
$a = new stdClass();
$a->hoge = 6;
$a->fuga = 11;
}
</code></pre>
<pre><code>class stdClass#1 (2) {
public $hoge =>
int(5)
public $fuga =>
int(10)
}
class stdClass#1 (2) {
public $hoge =>
int(0)
public $fuga =>
int(10)
}
</code></pre>
<p>なんで、みんな①と②だけ説明して、このコードを書いてくれなかったんだろう。(見つけてないだけで書いてるのかな?)<br />
……みんな①と②だけでわかるのか。俺の頭がわるいのか。</p>
<p>逆にこれを見て、何がわかったのかわからない、という人の方が多いのかも。<br />
なんというか、これをうまく言語化できない。<br />
うまく言語化できそうになったら書き直す。(かもしれない)</p>
hammhiko
tag:crieit.net,2005:PublicArticle/15080
2019-06-09T23:58:56+09:00
2019-06-09T23:58:56+09:00
https://crieit.net/posts/fetch-fetch
fetchがよくわからなかったのでオレオレfetchを作って雰囲気を掴む
<p>前回、<a href="https://crieit.net/posts/Promise-Promise">こんな記事</a>を書きました。<br />
上の記事のそもそもの発端は、fetchを使おうとしたけども、よくわからなかったからというものでした。<br />
根本的には、fetchがわからないというよりはPromiseがよくわかってなかったという方が近いので、前回Promiseの雰囲気を掴んだ時点で7割方解決しているのだけれど、そもそもの発端を解決させようと思います。</p>
<h2 id="そもそもの発端"><a href="#%E3%81%9D%E3%82%82%E3%81%9D%E3%82%82%E3%81%AE%E7%99%BA%E7%AB%AF">そもそもの発端</a></h2>
<p>超絶ざっくり書くと、fetchというのは下記のようになるかと。</p>
<pre><code class="JavaScript">fetch(url)
.then((response)=>{
return response.json();
})
.then(()=>{
//json使って何か処理
})
.catch((error)=>{
//エラー処理
})
</code></pre>
<p>まあ、こんな感じのものを見て、非同期をよくわかっていなかった僕はちんぷんかんぷんになって、どうにか、fetchというのは非同期で動くものらしい、というところまではわかった。<br />
なのでどうにかして非同期を勉強しなければいけない。<br />
そこでググったら出てくるわけです。</p>
<pre><code class="JavaScript">const hoge = ()=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('wait 3 sec!')
resolve('wait 3 sec!')
},3000)
})
}
</code></pre>
<p>……。さっきまでPromiseとかresolveとかrejectとか出てこなかったじゃん。<br />
ってなって挫折していた。<br />
今思えば至極単純で、Promiseとかresolveとかrejectとかはfetchの中で勝手にやっていることなので、fetchを使う分には登場しない。<br />
もちろん、理解する必要はあって、そのために今回もオレオレfetchを作ることで雰囲気を掴もうと思う。</p>
<h2 id="注意"><a href="#%E6%B3%A8%E6%84%8F">注意</a></h2>
<p>あくまで雰囲気を掴むだけです。実際の実装は微塵も知りません。<br />
いろんなドキュメントを読んだ上での筆者の解釈(を筆者の実装レベルでできるとこだけ再現したもの)です。とんちんかんかもしれません。<br />
妥協しまくりです。<br />
あまりにもとんちんかんなこと言ってたら教えて下さい。<br />
信用しないでください。<br />
レベル不足でクソコードです。</p>
<h2 id="まず呼び出すコードから"><a href="#%E3%81%BE%E3%81%9A%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%99%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8B%E3%82%89">まず呼び出すコードから</a></h2>
<p>こんな感じのjsonを作ります。<br />
json-serverとかで適当にapiを作ります。</p>
<pre><code class="json">{
"wizards":[
{
"id":1,
"name":"Arietta",
"feature":"monster"
},
{
"id":2,
"name":"Relum",
"feature":"fool"
},
{
"id":3,
"name":"Elise",
"feature":"poor"
}
]
}
</code></pre>
<p>で、呼び出し側</p>
<pre><code class="html"><html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="promise.js"></script>
<script type="text/javascript" src="fetch.js"></script>
<script type="text/javascript" src="index.js"></script>
<style>
table{
border:solid 1px;
}
th{
border:solid 1px;
}
td{
border:solid 1px;
}
</style>
</head>
<body>
hello async
<button onclick="getData()">
fetch
</button>
<table >
<thead>
<th>id</th>
<th>name</th>
<th>feature</th>
</thead>
<tbody id="tbody">
</tbody>
</table>
</body>
</html>
</code></pre>
<pre><code class="JavaScript">const getData = () => {
const url = 'https://localhost:3000/wizards' //json-serverとかでよしなに
fetch(url)
//oreoreFetch(url) //これに置き換えても動くようにするのが目標
.then((response)=>{
return response.json();
})
.then((json)=>{
const tbody = document.getElementById('tbody');
json.forEach((wiz)=>{
let tr = ` <tr>
<td>${wiz.id}</td>
<td>${wiz.name}</td>
<td>${wiz.feature}</td>
</tr>
`;
tbody.insertAdjacentHTML("beforeend",tr);
});
})
}
</code></pre>
<p><a href="https://crieit.now.sh/upload_images/59edc21d3f7f537d3dfb5ec99e2cfb135cf9c8d15ca25.JPG" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/59edc21d3f7f537d3dfb5ec99e2cfb135cf9c8d15ca25.JPG?mw=700" alt="WS000001.JPG" /></a><br />
まー、動くよね</p>
<h2 id="で、fetchのコード"><a href="#%E3%81%A7%E3%80%81fetch%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89">で、fetchのコード</a></h2>
<pre><code class="JavaScript">const oreoreFetch = (url)=>{
return new Promise((resolve,reject)=>{
httpRequest(resolve,reject,url)
});
//最終的に前回のオレオレPromiseで動いてほしい
//けど、Promiseチェーンが実装できなかったんだよな…
//return new oreorePromise((resolve,reject)=>{
// httpRequest(resolve,reject,url)
//});
}
const httpRequest = (resolve,reject,url) =>{
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
switch ( xhr.readyState ) {
//めんどいので4以外省略
case 0:
break;
case 1: // データ送信中.
break;
case 2: // 応答待ち.
break;
case 3: // データ受信中.
break;
case 4: // データ受信完了.
if( xhr.status == 200 || xhr.status == 304 ) {
const data = new oreoreResponse(xhr.responseText);
resolve(data);
} else {
reject(xhr.statusText);
}
break;
}
}
xhr.open( 'GET', url, true );
xhr.send(null);
}
class oreoreResponse{
constructor(data){
this.data = data;
}
json(){
return JSON.parse(this.data);
}
}
</code></pre>
<p>fetchができればいいのでResponseクラスは適当です。<br />
(実際はコンストラクタに引数はないし、jsonメソッドはPromiseを返す)<br />
Promiseの勉強で出てきたresolveとかrejectは(たぶん)fetchの中にあって、よしなにやってくれるので、fetchを使う分には意識しなくていいよ、ってのがわかる。</p>
<p>ということで動かす。</p>
<pre><code class="JavaScript">const getData = () => {
const url = 'https://localhost:3000/wizards'
//fetch(url)
oreoreFetch(url) //これに置き換えても動くようにするのが目標
.then((response)=>{
return response.json();
})
.then((json)=>{
const tbody = document.getElementById('tbody');
json.forEach((wiz)=>{
let tr = ` <tr>
<td>${wiz.id}</td>
<td>${wiz.name}</td>
<td>${wiz.feature}</td>
</tr>
`;
tbody.insertAdjacentHTML("beforeend",tr);
});
})
}
</code></pre>
<p><a href="https://crieit.now.sh/upload_images/8b94c3234843b3b4306df2d82355801c5cf9c8ec8f968.JPG" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8b94c3234843b3b4306df2d82355801c5cf9c8ec8f968.JPG?mw=700" alt="WS000000.JPG" /></a><br />
まー、それっぽく動く。</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>みんな、async/await使おうぜ!</p>
hammhiko
tag:crieit.net,2005:PublicArticle/15072
2019-06-07T00:25:00+09:00
2019-06-07T07:58:46+09:00
https://crieit.net/posts/Promise-Promise
PromiseがよくわからなかったのでオレオレPromiseを作って雰囲気を掴む
<p>非同期がわかりません。<br />
「この関数はPromiseを返します」<br />
Promiseって何だよ。<br />
非同期やってもコールバック地獄にならないらしいけど、<br />
結局引数に渡すのはコールバックだし、<br />
僕からするとまーまーわからんのです。</p>
<p>というわけでPromiseを自作して雰囲気を掴むことにしました。</p>
<h2 id="注意"><a href="#%E6%B3%A8%E6%84%8F">注意</a></h2>
<p>あくまで雰囲気を掴むだけです。実際の実装は微塵も知りません。<br />
いろんなドキュメントを読んだ上での筆者の解釈(を筆者の実装レベルでできるとこだけ再現したもの)です。とんちんかんかもしれません。<br />
妥協しまくりです。<br />
Promise.allとかやりません。それどころかPromiseチェーンすらできません。<br />
catchは実装したけど試してません。<br />
(要はほとんどできてないじゃないか)</p>
<p>あまりにもとんちんかんなこと言ってたら教えて下さい。<br />
信用しないでください。<br />
レベル不足でクソコードです。</p>
<h2 id="とりあえずコード"><a href="#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A%E3%82%B3%E3%83%BC%E3%83%89">とりあえずコード</a></h2>
<p>とりあえずよく呼び出す側のコードです。</p>
<pre><code class="html"><html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>オレオレPromise</title>
<script type="text/javascript" src="promise.js"></script>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
hello async
<button onclick="wait()">
async start
</button>
<p id="start" style="display:none"></p>
<p id="async" style="display:none"></p>
<p id="finish" style="display:none"></p>
</body>
</html>
</code></pre>
<pre><code class="JavaScript">const wait = ()=>{
const start = document.getElementById('start');
start.style="";
start.innerHTML += "start:" + new Date();
hidouki().then(finish).catch(dispError);
}
const hidouki = ()=>{
return new Promise(wait1);
//return new oreorePromise(wait1); //こっちに書き換えても動くようになるのが目標
}
const wait1 = (resolve,reject) => {
setTimeout(() => {
const async1 = document.getElementById('async');
async1.style="";
async1.innerHTML += "wait3 sec :" + new Date();
resolve('succeeded async');
},3000);
}
const finish = (value) => {
setTimeout(()=>{
const finish = document.getElementById('finish');
finish.style = "";
finish.innerHTML += value + " :" + new Date();
},5000);
}
const dispError = (error) => {
alert(error);
}
</code></pre>
<p><a href="https://crieit.now.sh/upload_images/7582dd8ee85437bbc45010a0c82f6a3d5cf92fb6c3701.JPG" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7582dd8ee85437bbc45010a0c82f6a3d5cf92fb6c3701.JPG?mw=700" alt="WS000004.JPG" /></a><br />
ちゃんと待ってる。</p>
<p>さて、new Promiseしているところを自作Promiseに書き換えても動くようにするのが目標です。</p>
<h2 id="わからんなりの実装"><a href="#%E3%82%8F%E3%81%8B%E3%82%89%E3%82%93%E3%81%AA%E3%82%8A%E3%81%AE%E5%AE%9F%E8%A3%85">わからんなりの実装</a></h2>
<p>正直、Promiseのコンストラクタの引数はコールバック関数で、そのコールバック関数の引数はresolveとrejectで……、<br />
って言われてわかる? みんなすごいね! 僕はわかんないです。そのresolveとrejectはどこから来たんだよ。<br />
ってのを試行錯誤しながら理解しようとした結果、以下のようになりました。</p>
<pre><code class="JavaScript">class oreorePromise{
constructor(callback){
this.value = null;
this.state = 'pending';
this.thenTimer = [];
this.catchTimer = [];
callback(this.resolve.bind(this),this.reject.bind(this));
}
resolve(value){
this.value = value;
this.state ='fulfilled';
}
reject(value){
this.value = value;
this.state='rejected';
}
then(nextCallback){
this.thenTimer.push(setInterval(function(){
if(this.state === 'fulfilled'){
this.value = nextCallback(this.value);
clearInterval(this.thenTimer.shift());
}
else if(this.state === 'rejected'){
//待機やめる
clearInterval(this.thenTimer.shift());
}
}.bind(this),100)); //テストだし100ミリ秒くらい待とう
// https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises#Chaining
// then 関数は元の Promise とは別の新しい Promise を返します。
// らしいけど、もう力尽きた…。
return this;
}
catch(errorCallback){
this.catchTimer.push(setInterval(function(){
if(this.state === 'fulfilled'){
//待機やめる
clearInterval(this.catchTimer.shift())
}
else if(this.state === 'rejected'){
errorCallback(this.value);
clearInterval(this.catchTimer.shift())
}
}.bind(this),100));
}
}
</code></pre>
<p>JavaScriptのthisがわかんなくて、ただでさえわからないのにコールバックしまくってthisが迷子になって結構しんどかった。一応動いたけど。<br />
<strong>Promiseよりthisの方が難しかった。</strong><br />
だれかthis教えて。</p>
<p>resolveとrejectはPromiseオブジェクトが持つメソッドで、<br />
「コンストラクタに引数として渡したコールバック関数を実行するときに、resolveとrejectを引数として実行しますよ。<br />
なので、実行したい関数を定義するときにresolveとrejectが引数になるように定義してくださいね」<br />
という<strong>お約束</strong>だということが自分で書いてようやくわかった。</p>
<p>わかってからだと、ちゃんと<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#Parameters">書いてある</a>ことがわかる。なぜ最初から見つけられないのだ。</p>
<p>どこかの解説記事で、<br />
「resolve関数を実行するとthenメソッドが呼び出される」<br />
とか書いてあって腑に落ちなかったんだけど、たぶん、正しいのは、<br />
「thenメソッドは即座に呼ばれていて、オブジェクトの持つ状態(oreorePromiseではプロパティstate)がfulfilledになるまで、引数として渡されたコールバック関数の実行を待つ」<br />
なんだと思う。<br />
(自信はない)<br />
resolveは状態を変更しているだけで、別にthenに渡された関数を実行しているとかはない、と思う。(ここは特に自信ない)</p>
<p>最初にそう言う説明を見てしまったのでthenメソッドが魔法のように見えてしまっていたのだけれど、<br />
(MDNで「<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises#Chaining">さあ魔法の時間です。</a>」とか言ってるしね!)<br />
よく見ればobject.method()という至極基本的な文法だし、即座に呼ばれて当然だよなと。</p>
<p>このコードでは、状態が変わるまでsetIntervalでループしてるのは最高にダサいと思うけど、本質とずれるのであまり凝ってない。</p>
<h2 id="できたので書き換えてみる"><a href="#%E3%81%A7%E3%81%8D%E3%81%9F%E3%81%AE%E3%81%A7%E6%9B%B8%E3%81%8D%E6%8F%9B%E3%81%88%E3%81%A6%E3%81%BF%E3%82%8B">できたので書き換えてみる</a></h2>
<pre><code>const hidouki = ()=>{
//return new Promise(wait1);
return new oreorePromise(wait1); //こっちに書き換えても動くようになるのが目標
}
</code></pre>
<p><a href="https://crieit.now.sh/upload_images/b839e5e7f02980a5b56afc20fd54d5625cf92fd3dacfc.JPG" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b839e5e7f02980a5b56afc20fd54d5625cf92fd3dacfc.JPG?mw=700" alt="WS000005.JPG" /></a></p>
<p>動いた。</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>ドキュメントを見返して、ソースを見返す度に「あ、ここ違うな」ってなる。<br />
ただ、重ね重ねだけど、雰囲気を掴んでPromiseを使えるようになるのが目的で、Promiseのコピーを作りたいとかではない。<br />
せめてPromiseチェーンは実装したかったけど、費用対効果が薄すぎてやめた。<br />
個人的には</p>
<blockquote>
<p>resolveとrejectはPromiseオブジェクトが持つメソッドで、<br />
「コンストラクタに引数として渡したコールバック関数を実行するときに、resolveとrejectを引数として実行しますよ。<br />
なので、実行したい関数を定義するときにresolveとrejectが引数になるように定義してくださいね」<br />
という<strong>お約束</strong>だということが自分で書いてようやくわかった。</p>
<p>どこかの解説記事で、<br />
「resolve関数を実行するとthenメソッドが呼び出される」<br />
とか書いてあって腑に落ちなかったんだけど、たぶん、正しいのは、<br />
「thenメソッドは即座に呼ばれていて、オブジェクトの持つ状態(oreorePromiseでは変数名state)がfulfilledになるまで、引数として渡されたコールバック関数の実行を待つ」<br />
なんだと思う。<br />
(自信はない)</p>
</blockquote>
<p>ここが理解できた時点でもういいかって感じ。おまけで完成させた。</p>
<h2 id="まとめ2"><a href="#%E3%81%BE%E3%81%A8%E3%82%812">まとめ2</a></h2>
<p>みんな、async/await使おうぜ!</p>
<h2 id="まとめ3"><a href="#%E3%81%BE%E3%81%A8%E3%82%813">まとめ3</a></h2>
<p>だれかthis教えて</p>
hammhiko
tag:crieit.net,2005:PublicArticle/14890
2019-03-28T19:12:26+09:00
2019-03-28T19:12:26+09:00
https://crieit.net/posts/chrome-UTF-8
ブラウザ(chrome)のデフォルトエンコードってUTF-8じゃないの?
<p>まー、困ることはないんだけど、気になって気になって</p>
<h1 id="発端"><a href="#%E7%99%BA%E7%AB%AF">発端</a></h1>
<p>よく、jsとかの挙動で「あれ、どうだっけ?」ってなった時、</p>
<pre><code><html>
<head>
</head>
<body>
<button onclick="test()">
test
</button>
<script src="index.js">
</body>
</html>
</code></pre>
<p>とかで、</p>
<pre><code>docker run -d -p 8888:80 -v `pwd`:/usr/local/apache2/htdocs httpd
</code></pre>
<p>で、さくっと試したりする。(果たしてこれがさくっとなのか)<br />
まー、見てわかる通り、htmlはあまりにも手抜きすぎるんだけど。<br />
動くし、すぐ使い終わるから。</p>
<p>んで、ある時、</p>
<pre><code><html>
<head>
</head>
<body>
<button onclick="test()">
てすと
</button>
<script src="index.js">
</body>
</html>
</code></pre>
<p>ってやったら、見事に文字化けした。<br />
(macのchrome)</p>
<h1 id="対処はわかる。わかるんだけど…"><a href="#%E5%AF%BE%E5%87%A6%E3%81%AF%E3%82%8F%E3%81%8B%E3%82%8B%E3%80%82%E3%82%8F%E3%81%8B%E3%82%8B%E3%82%93%E3%81%A0%E3%81%91%E3%81%A9%E2%80%A6">対処はわかる。わかるんだけど…</a></h1>
<p>対処としては簡単で、</p>
<pre><code><html>
<head>
<meta charset="utf-8"></meta>
</head>
<body>
<button onclick="test()">
てすと
</button>
<script src="index.js">
</body>
</html>
</code></pre>
<p>metaタグでcharset指定するだけなんだけど。</p>
<p>ファイル自体はUTF-8で作成していたし、UTF-8なら大丈夫だろ、とか思ってたからちょっとびっくりした。<br />
デフォルトでUTF-8じゃないのか。<br />
気になったので調べようと思った。</p>
<h1 id="調べた"><a href="#%E8%AA%BF%E3%81%B9%E3%81%9F">調べた</a></h1>
<h1 id="わかんなかった"><a href="#%E3%82%8F%E3%81%8B%E3%82%93%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F">わかんなかった</a></h1>
<p>「指定しないと文字化けする可能性があるので、ちゃんと指定しましょう」<br />
そんなことはわかってるんだ。<br />
わかった上で、指定しなかったらどうなるか知りたいんだ。<br />
指定しなかったら文字化けする? 違う、そうじゃない。いや、そうなんだけど、そうじゃない。知りたいのはそこじゃない。どのエンコーディングが採用されるのか、だ。</p>
<p>apacheにAddDefaultCharsetとかなかったし、ブラウザ側だと思うんだけどなー。</p>
<p>それっぽいこと書いてある<a target="_blank" rel="nofollow noopener" href="http://www.ic.daito.ac.jp/~mizutani/html/default_encode.html">サイト</a>もあったが、ちょっと古い。<br />
chrome ver.35って。俺のchrome、ver.73だぞ。そんな項目ねーよ。<br />
というか、chromeは<a target="_blank" rel="nofollow noopener" href="https://www.beginnerweb.net/chrome.html">もうエンコード指定できない</a>。<br />
まー、大半のユーザーは「エンコードとは何ぞ」って感じだから、意識させないってのは、わからなくもない。charset指定しないサイトなんて今時ないだろうし。でも、だからこそ、なおのこと指定しなかった場合の挙動がよくわからん。</p>
<p>普段、ちゃんと作る時は、まず間違いなく指定するmetaタグだし、わからなくても困らないっちゃ困らないし、不毛なので調べるのをやめた。</p>
<h1 id="結論"><a href="#%E7%B5%90%E8%AB%96">結論</a></h1>
<ul>
<li>エンコードはちゃんと指定しよう</li>
<li>どなたか、ご存知でしたら優しく教えてください。</li>
</ul>
hammhiko
tag:crieit.net,2005:PublicArticle/14879
2019-03-25T19:00:00+09:00
2019-03-25T19:00:00+09:00
https://crieit.net/posts/windows10-elementary-os
windows10からelementary os へリモートデスクトップ接続する
<p>めちゃくちゃハマった。<br />
祝日が溶けた。</p>
<h1 id="結論"><a href="#%E7%B5%90%E8%AB%96">結論</a></h1>
<p>chromeリモートデスクトップ<br />
ただし、それすらもハマる</p>
<h1 id="発端"><a href="#%E7%99%BA%E7%AB%AF">発端</a></h1>
<p>古いwindows PCが余ってたので、Linuxでも入れて遊ぼうかと。<br />
古いPCって言ってるのに(スペック要求の高い)elementary os かよって話はあるけども。</p>
<p>入れたは良いけども、PC2台をデスクに並べて別々にキーボードとマウス操作するのはだるいので、windowsからリモート接続しようと試みた。</p>
<p>windowsならリモートデスクトップ接続(mstsc.exe)で簡単という認識だったのだけれど、windows→Linuxはどうなんだろ?<br />
と、軽くググってみたところ、どうもxrdpというのでいけるらしい。</p>
<h1 id="xrdpで詰まる"><a href="#xrdp%E3%81%A7%E8%A9%B0%E3%81%BE%E3%82%8B">xrdpで詰まる</a></h1>
<p>……繋がんねー</p>
<pre><code>sudo apt install xrdp
</code></pre>
<p>でとりあえず使える、みたいなこといろんなとこに書いてあるのに、繋がんねー。<br />
ログみても</p>
<pre><code>some problem
</code></pre>
<p>とか書いてあってさっぱりわかんねー。</p>
<p>で、いろいろ試行錯誤しすぎて、どのページ見たのかわからなくなったのだけど、たぶん<a target="_blank" rel="nofollow noopener" href="https://www.hiroom2.com/2018/05/07/ubuntu-1804-xrdp-xfce-ja/">このへん</a>あたり見て設定したらとりあえず繋がった。<br />
のだけれど。</p>
<p>見た目が全然違う。</p>
<p>なんか、青くてDebianとか書いてある(あった気がする)。<br />
(スクショは撮ってない)<br />
僕の気に入った綺麗なelementary os のデスクトップはどこに行ったの?</p>
<h1 id="デスクトップ環境云々"><a href="#%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E7%92%B0%E5%A2%83%E4%BA%91%E3%80%85">デスクトップ環境云々</a></h1>
<p>普段はwindows使って、Linuxはサーバー用途でCUIのみ、とかやってると馴染みがないけど、Linuxにはデスクトップ環境がたくさんある。<br />
windowsはOSとデスクトップが密になっているけど、Linuxはそうじゃない(気がする)<br />
windowsだと、いつも見ているあの画面がそのままリモートでって感じになるけど、Linux(というかxrdp?)だと、「指定したデスクトップ環境の見た目をエミュレートした結果をmstsc.exeに見せている」って感じなのかな。自信はない。<br />
で、上のリンク見て僕はxfceのデスクトップ環境を指定していた。</p>
<p>つまり例えるなら、firefoxを立ち上げて、「chromeの見た目じゃない!」って騒いでいるようなもの。バカじゃん、俺。</p>
<p>正直なところ、elementary os を使う理由ってあのデスクトップ環境なところが大部分占めてるので(でなきゃUbuntu使ってるなー)、別のデスクトップじゃ意味がない。</p>
<p>じゃあつまり、elementary os のデスクトップ環境と同じのを指定すれば良いんだなと。elementary os のデスクトップ環境はPantheonっていうらしい。教えてgoogle先生!</p>
<p>……なさそう。</p>
<p>調べ方が悪いのか、調べても出てこないし、適当に.xsession書き換えてみたけどダメだった。<br />
代わりに見つけたのが<a target="_blank" rel="nofollow noopener" href="https://www.reddit.com/r/elementaryos/comments/8iorv5/connect_to_remote_desktop/">これ</a></p>
<p>英語苦手なんだけど、雰囲気で読んでみたら、たぶんこんなこと言ってる。</p>
<p><em>「elementary os でxrdpリモートデスクトップしたいけどできないんだけど」<br />
「xfceデスクトップ環境をインストールしてxrdpで指定すれば繋がるけど、見た目変わっちゃうよ。見た目変えたくないなら諦めてchromeリモートデスクトップ使えば?」</em></p>
<p>まじか。</p>
<h1 id="chromeリモートデスクトップでも詰まる"><a href="#chrome%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E3%81%A7%E3%82%82%E8%A9%B0%E3%81%BE%E3%82%8B">chromeリモートデスクトップでも詰まる</a></h1>
<p>chromeリモートデスクトップなら使ったことあるし、<a target="_blank" rel="nofollow noopener" href="https://support.google.com/chrome/answer/1649523">公式のヘルプ</a>見ればすぐできるだろとか思ったら、そうは問屋が卸さなかった。(問屋なら卸せよ)</p>
<p>ヘルプの通り設定したら、繋がった。<br />
繋がった、けど。<br />
壁紙だけ出て、何も操作できない。<br />
何か設定ミスったかと思って見返してみても問題なさそう。<br />
お決まりの再起動とかしてみても変わらず。</p>
<p>調べて見たら<a target="_blank" rel="nofollow noopener" href="https://qiita.com/minecraft/items/452671c93822ba06a1c4">同じような現象があった</a>のでその通りやってみたら、今度は繋がりすらしない。</p>
<p>さらに調べた結果、<a target="_blank" rel="nofollow noopener" href="https://webnetforce.net/ubuntu-chrome-remote-trouble/">見つけた</a>。<br />
内容の説明もちゃんとあって、わかりやすかった。</p>
<p>繋がった。<br />
歓喜。</p>
<h1 id="レスポンスは?"><a href="#%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%81%AF%EF%BC%9F">レスポンスは?</a></h1>
<p>以前、chromeリモートデスクトップ使った時は、結構動作がもっさりしてて、だから最初の選択肢になかったのだけれど、使ってみたらあまりストレス感じなかった。</p>
<p>前使った時は、windows→windowsで、ネットワークもグローバル越しだったので負荷が高かったのかも。何年か前だしアプリも改良されているのかも。</p>
<h1 id="教訓"><a href="#%E6%95%99%E8%A8%93">教訓</a></h1>
<ul>
<li>あまり情報のなさそうなやつは修羅の道と心得よ<br />
(Ubuntuだったらここまでハマらなかった気がする)</li>
<li>英語の情報もちゃんと読もう<br />
(みんな言ってることだけど、改めて)</li>
<li>自分がやっていることをちゃんと理解すること<br />
(あまり説明のないものをコピペ、とかやると動かなくなるし、何が悪いかもわからない)</li>
</ul>
hammhiko
tag:crieit.net,2005:PublicArticle/14806
2019-02-17T20:26:45+09:00
2019-04-26T23:36:25+09:00
https://crieit.net/posts/2a4b0703c5a2b984205edb23497fcecd
三項演算子って初見殺しだよなって話
<p>別に、巷でよくある「三項演算子使え・使うな論争」ではなくて。<br />
単純に「三項演算子って初見殺しだよな」っていう感想であって、<br />
それ以上でもそれ以下でもないです。</p>
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>もし、以下のような検索でここにたどり着いた人<br />
+ C# ? :<br />
+ PHP はてな コロン<br />
+ Javascript クエスチョン コロン</p>
<p>君の探しているものはこれだよね?</p>
<pre><code>string hoge = fuga ? piyo : piyopiyo
</code></pre>
<p>これは、「三項演算子」って言います。 <br />
三項演算子って何? っていうのは、「三項演算子」でググり直してね。<br />
残念ながらこの記事には説明はないよ。ごめんね。</p>
<h1 id="というわけで"><a href="#%E3%81%A8%E3%81%84%E3%81%86%E3%82%8F%E3%81%91%E3%81%A7">というわけで</a></h1>
<p>三項演算子って初見殺しというか、初心者に優しくないよなーと。<br />
いくつか理由をば。</p>
<h2 id="入門書に載ってない"><a href="#%E5%85%A5%E9%96%80%E6%9B%B8%E3%81%AB%E8%BC%89%E3%81%A3%E3%81%A6%E3%81%AA%E3%81%84">入門書に載ってない</a></h2>
<p>いや、載ってるかもしれないけど。<br />
だいたい、ifとかswitchは載ってるけど、三項演算子は載ってないイメージ。<br />
(そもそも三項演算子は演算子であって、文であるifやswitchとは違う云々とかはとりあえず置いておく)<br />
というか入門書読んでるレベルの初心者は三項演算子の説明があってもスルーすると思う。</p>
<h2 id="検索しにくい"><a href="#%E6%A4%9C%E7%B4%A2%E3%81%97%E3%81%AB%E3%81%8F%E3%81%84">検索しにくい</a></h2>
<p>ということで三項演算子を学ばなかった初心者くん。<br />
(入社・配属とか色々あって)他人のソースを見る機会を得て、初めて三項演算子に出会います。</p>
<p>「え、何、これ?」</p>
<p>わからないことはとりあえずググりましょう。</p>
<pre><code>C# ? :
</code></pre>
<p>oh...<br />
ダメです。それじゃあ「C Sharp - ウィキペディア」みたいな検索結果しか出ませんね。<br />
googleで記号を検索するのは難しいですね。</p>
<p>シングルクォーテーションで囲えって? それができれば初心者やってないよ!</p>
<p>日本語に直せって? それがで(ry<br />
いや、日本語にするのは少し考えればわかるんですけどね。状況によってはテンパってて愚直に記号で検索して出てこなくて余計にテンパったりするんですよね。初心者だし。</p>
<h2 id="そんなことも知らないの恐怖症"><a href="#%E3%81%9D%E3%82%93%E3%81%AA%E3%81%93%E3%81%A8%E3%82%82%E7%9F%A5%E3%82%89%E3%81%AA%E3%81%84%E3%81%AE%E6%81%90%E6%80%96%E7%97%87">そんなことも知らないの恐怖症</a></h2>
<p>じゃあ、先輩に聞けよって話になると思うんですけどね。<br />
聞きづらいじゃないですか、散々「そんなことも知らないの?」って言われ続けてるんですから。<br />
初心者は「そんなことも知らないの? なこと」と「それは知らなくても仕方ないね、なこと」の区別って難しいじゃないですか。<br />
(三項演算子ってどっちだろう?)</p>
<p>ってことで、「それを今わからないと困るのか」ということを悩んだ結果、後回しにする、という結論になることも。(数年前の僕ですね)</p>
<h1 id="とにかく答えに辿り着きづらい"><a href="#%E3%81%A8%E3%81%AB%E3%81%8B%E3%81%8F%E7%AD%94%E3%81%88%E3%81%AB%E8%BE%BF%E3%82%8A%E7%9D%80%E3%81%8D%E3%81%A5%E3%82%89%E3%81%84">とにかく答えに辿り着きづらい</a></h1>
<p>一応、無理やり理由を3つひねり出してみましたけど、個人的には、<br />
<strong>ググりにくい</strong><br />
これに尽きると思うんですよね。<br />
まあ、三項演算子に限ったことじゃなくて、PHPのアロー演算子とか、<strong>記号で検索せざるを得ない</strong>ものって答えに辿り着きにくいと思うのです。</p>
<p>それの対応ってなかなか難しくて<strong>検索の仕方の経験値を上げる</strong>しかないのかなーと。<br />
どうにかなんないかなー。</p>
<h1 id="結論"><a href="#%E7%B5%90%E8%AB%96">結論</a></h1>
<p>ないよそんなもん。<br />
ただの感想だって最初に言ったじゃん。</p>
<h1 id="HELP!"><a href="#HELP%21">HELP!</a></h1>
<p>マークダウン詳しくないんでけど、<br />
リストがうまく作れないのと、<br />
C#の#が見出し認定されるみたいで目次に出ちゃうんですけど、どうすればいいですか? 誰か教えて。</p>
hammhiko
tag:crieit.net,2005:PublicArticle/14804
2019-02-16T11:42:15+09:00
2019-02-16T12:50:42+09:00
https://crieit.net/posts/bc030f9bc7008b5c0eb13a9cc3989831
非同期がわからないのはゲシュタルト崩壊を起こしていたからだ
<p>ということに気が付いた。</p>
<p>すげーあほなこといってます。</p>
<h1 id="よくある?サンプル"><a href="#%E3%82%88%E3%81%8F%E3%81%82%E3%82%8B%EF%BC%9F%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB">よくある?サンプル</a></h1>
<pre><code>fetch(url)
.then(function(response){
//fetchで返ってきたデータをjson形式にする
return response.json();
})
.then(function(json){
//jsonで何か処理する
doSomething(json);
})
.catch(function(error){
//エラー発生
console.log(error);
})
</code></pre>
<p>(async/await使えよって指摘はごもっともなんですが……)<br />
初見で見たときすごい未知の呪文に見えたんですね。<br />
で、なんとなく真似てやってみても、ちょっと変えようとすると動かない、みたいな。<br />
めっちゃ変な書き方しちゃう、みたいな。</p>
<p>「thenはメソッドで引数にコールバックを指定します。」<br />
ただこれだけなのに、なぜか謎の呪文に見えていた時期があった。</p>
<h1 id="アホの極み"><a href="#%E3%82%A2%E3%83%9B%E3%81%AE%E6%A5%B5%E3%81%BF">アホの極み</a></h1>
<p>というか今までthenのメソッドチェーンが特殊な記法に見えていたんだけど、これって<br />
<strong>(fetchが返す)Promiseオブジェクトが持つthenメソッド</strong><br />
じゃん。普通の書き方じゃん。A.B()じゃん。PHP風に書くとA->B()じゃん。<br />
え、なんでこんなこと今まで気づかなかったの、俺。馬鹿じゃん。</p>
<p>たぶん、メソッドの引数がコールバックで、しかも無名関数で書かれているから、その時点でちょっと複雑になって、<br />
しかも<strong>括弧と波括弧とfunctionがゲシュタルト崩壊</strong>起こして謎の呪文に見えていたんだな。きっと。<br />
実際はもっと処理が書いてあって複雑だし。</p>
<p>あと、メソッドの部分で改行するのも馴染みがない。<br />
そりゃ、長くなるからわかるんだけども、なんか、ねえ……。<br />
だって、</p>
<pre><code>mojiretsu
.substring(0,5);
</code></pre>
<p>とか普通書かないじゃん。<br />
(意外と書くのかな?)</p>
<p>なんかこの辺、コーディング規約とかあるのかな?</p>
<h1 id="ということで書き直す"><a href="#%E3%81%A8%E3%81%84%E3%81%86%E3%81%93%E3%81%A8%E3%81%A7%E6%9B%B8%E3%81%8D%E7%9B%B4%E3%81%99">ということで書き直す</a></h1>
<pre><code>function convertToJson(response){
//fetchで返ってきたデータをjson形式にする
return response.json();
}
function doSomething(json){
//json使って何か処理する
doSomething(json);
}
function addErrorLog(error){
//エラー発生
console.log(error);
}
fetch(url).then(convertToJson).then(doSomething).catch(addErrorLog);
</code></pre>
<p>(アロー関数使えって指摘はごもっともなんですけどね……)<br />
これならもっと理解早かったわ、きっと。<br />
まあ、この次にPromiseとかコールバックを理解するっていう壁があるんですけどね。<br />
thenメソッドに渡したコールバック関数の引数って何だよ、とか。<br />
その辺は別の記事で書くかもしれない。</p>
<h1 id="教訓"><a href="#%E6%95%99%E8%A8%93">教訓</a></h1>
<p>サンプルがわからないときは自分がわかるように分解・再構築するとわかりやすいかも。<br />
アロー関数がわからない(慣れてない)ならfunctionに直すとか。<br />
(アロー関数は覚える必要があるという前提で。というか、こういう作業をやっていくと覚えやすいのでは)<br />
無名関数でゲシュタルト崩壊起こすなら、別関数に切り出すとか。<br />
あとは、まあ、いろいろ。</p>
<p>まあ、わからないから勉強しようとして、それがわからないんだから、直すのも一苦労だろうけど。<br />
わかるところから分解するしかないよなー。</p>
<p>当たり前だけど、自分で手を動かさなきゃわからんよね。</p>
<p>以上</p>
hammhiko