憧れ駆動開発 2013-08-24T01:39:53+09:00 atasatamatara Hatena::Blog hatenablog://blog/12704591929891294067 Opera 15.00 で Chrome の拡張機能をなんとなくうごかす(自己責任) hatenablog://entry/11696248318755270518 2013-07-02T23:21:54+09:00 2013-10-09T21:35:12+09:00 とても暫定的なてきとうな技術者的にはけっこうバッドな方法だと自覚しているので対処療法なのでやるかは自己責任。 Opera 15.00 リリース 12.15 から Opera Next だった 15 が今日リリースされました。前から言われていたとおり Chromium ベースのものです。Presto とか Carakan のそれではないです。設定項目もすごく簡略化されて、いまのところツールバーまわりいじれないですね*1。UAは Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko)… <p>とても暫定的なてきとうな技術者的にはけっこうバッドな方法だと自覚しているので対処療法なのでやるかは自己責任。</p> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> 15.00 リリース</h3> <p>12.15 から <a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> Next だった 15 が今日リリースされました。前から言われていたとおり <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chromium">Chromium</a> ベースのものです。Presto とか Carakan のそれではないです。設定項目もすごく簡略化されて、いまのところツールバーまわりいじれないですね<a href="#f1" name="fn1" title="アドレスバーは下にしてURLは完全表示にしたい">*1</a>。<a class="keyword" href="http://d.hatena.ne.jp/keyword/UA">UA</a>は</p> <blockquote> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Mozilla">Mozilla</a>/5.0 (<a class="keyword" href="http://d.hatena.ne.jp/keyword/Macintosh">Macintosh</a>; <a class="keyword" href="http://d.hatena.ne.jp/keyword/Intel%20Mac">Intel Mac</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/OS%20X">OS X</a> 10_7_5) AppleWebKit/537.36 (<a class="keyword" href="http://d.hatena.ne.jp/keyword/KHTML">KHTML</a>, like <a class="keyword" href="http://d.hatena.ne.jp/keyword/Gecko">Gecko</a>) <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>/28.0.1500.52 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a>/537.36 OPR/15.0.1147.132</p> </blockquote> <p>とかなんとか OPR ってのがでてる。Mozzilaなのか <a class="keyword" href="http://d.hatena.ne.jp/keyword/Webkit">Webkit</a> なのか <a class="keyword" href="http://d.hatena.ne.jp/keyword/Gecko">Gecko</a> なのか <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a> なのか <a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a> なのかよくわからない感じになってますけど、OPR です。<a class="keyword" href="http://d.hatena.ne.jp/keyword/opera">opera</a>:config とかは config にリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C0%A5%A4">ダイ</a>レクトされます。</p><p>UI まわりやなんやらが変わっているのはおいておいて、とりあえず<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%B5%A1%C7%BD">拡張機能</a>はそのままでは動きません。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a> と <a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a> と <a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> それぞれの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%B5%A1%C7%BD">拡張機能</a>はだいたい似ている感じのはずですけど、manifest とかがちがうっぽいとかあります。12系までは HTML/<a class="keyword" href="http://d.hatena.ne.jp/keyword/CSS">CSS</a>/JS を詰め込んだ zip ファイルにパッケージして oex という拡張子にしていたはずだけど、今回 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chromium">Chromium</a> ベースのものなので crx/nex にするっぽいです。</p><p>ちなみに 12までの oex は <a href="http://dev.opera.com/extension-docs/tut_conversion.html">Converting OEX extensions to CRX/NEX - Opera 15+ extensions documentation</a> で変換できるっぽいです。</p> </div> <div class="section"> <h3>とりあえずうごかす(保証はない)</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Chrome">Google Chrome</a> でいれた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%B5%A1%C7%BD">拡張機能</a>はなんとなく動くかもしれません。</p> <ol> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a> の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%B5%A1%C7%BD">拡張機能</a>の設定から「<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D9%A5%ED%A5%C3%A5%D1">デベロッパ</a>ーモード」をチェックし、IDを確認します。</li> <li>その ID が ~/Library/Application Support/<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>/<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>/Default/Extensions/ とか C:\Users\username\AppData\Local\<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>\<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>\User Data\Default\Extensions とからへんに実体があります。</li> <li>バージョンを指定してフォルダごとコピーとかして <a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%B5%A1%C7%BD">拡張機能</a>設定の「開発者」から「パッケージ化されていない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%B5%A1%C7%BD">拡張機能</a>を読み込む」でフォルダを選択します</li> <li>とりあえずはいるようななにかがでます。警告とかきっとでます。</li> </ol><p>とりあえずいくつかいれてみましたがとりあえず動いたり動かなかったりします。</p> </div> <div class="section"> <h3>技術的な話</h3> <p><a href="http://dev.opera.com/extension-docs/index.html">Welcome! - Opera 15+ extensions documentation</a> によると .nex という拡張子にして <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chromium">Chromium</a> ベースな拡張だけど <a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> 用の manifest とかを用意してアップロード、ということになるんでしょうか。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> 特有としてはスピード<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C0%A5%A4">ダイ</a>アルまわりはさわれるようです。スタッシュとディスカバーまわりはどうなるのかな。スタッシュの<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>叩けて <a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> Link できたらちょっといいかもしれない。まあただそこはもう Pocket とかでやってる人のほうが多そうだけど、どうなんだろう<a href="#f2" name="fn2" title="マウスジェスチャーにしてもスピードダイアルにしてもブラウザ側で機能をつけてしまうことの意味は少しはわかる">*2</a>。 <br /> </p> </div> <div class="section"> <h3>これからの <a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a></h3> <p>どうなるんでしょうか。</p><p>個人的には <a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> はプロダクトだけじゃなくて音楽パネルやコミュニティや個人的な思い入れがわりとあるのでしばらく応援したいので使うとおもう。そしてこうして15でかわってしまうことで去ってしまう人へのひっかかりがあれば、まあ、うれしいかもしれない。気持ちが去ったら Firefix(Vimperator) にするかもしれないとは前から思っているし、機能なら <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a> でいい、拡張するなら <a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a> にすればいいとは前々からずっと思っていた。でも気分として <a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a>最強伝説(笑)が宗教なのはある。</p><p>もうひとつは、いままで UserJS 関係でお世話になった分を形にして返すというのもいいかな、とかは思ってます。揺れてますね。</p> <div class="section"> <h4>追記</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> アドオンとしてそもそも同じようなものがあるんですね……。後から知った<br /> <a href="https://addons.opera.com/ja/extensions/details/download-chrome-extension/?display=en">&#x62E1;&#x5F35;&#x6A5F;&#x80FD;&#x300C; Download Chrome Extension&#x300D; - Opera &#x30A2;&#x30C9;&#x30AA;&#x30F3;</a></p> </div> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">アドレスバーは下にしてURLは完全表示にしたい</span></p> <p class="footnote"><a href="#fn2" name="f2" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A6%A5%B9%A5%B8%A5%A7%A5%B9%A5%C1%A5%E3%A1%BC">マウスジェスチャー</a>にしてもスピード<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C0%A5%A4">ダイ</a>アルにしてもブラウザ側で機能をつけてしまうことの意味は少しはわかる</span></p> </div> atasatamatara クロスブラウザで確認するとき、modern.IE というIEテスト環境がすごい hatenablog://entry/11696248318753601770 2013-05-18T21:12:16+09:00 2013-05-18T21:12:16+09:00 初めて知った。英語は知らないけど日本語版はちょうど今年4月だから、わりと最近の話みたい。 Home | Testing made easier in Internet Explorer | modern.IE modern.IE の更新: VM の無料ダウンロード、Windows 8 QuickStart Kit、コード スキャン ツールの強化など - IEBlog 日本語 - Site Home - MSDN Blogsクラウドォォ上でシミュレートできるとか、どうやら仮想マシン用のVMを配ったりしているらしい。Windows, Mac はもちろん Linux にも対応しているし、Virtua… <p>初めて知った。英語は知らないけど日本語版はちょうど今年4月だから、わりと最近の話みたい。<br /> <a href="http://modern.ie/virtualization-tools">Home | Testing made easier in Internet Explorer | modern.IE</a><br /> <a href="http://blogs.msdn.com/b/ie_ja/archive/2013/04/08/new-on-modern-ie-free-vm-downloads-windows-8-quickstart-kits-enhanced-code-scanning-tools-and-more.aspx">modern.IE &#x306E;&#x66F4;&#x65B0;: VM &#x306E;&#x7121;&#x6599;&#x30C0;&#x30A6;&#x30F3;&#x30ED;&#x30FC;&#x30C9;&#x3001;Windows 8 QuickStart Kit&#x3001;&#x30B3;&#x30FC;&#x30C9; &#x30B9;&#x30AD;&#x30E3;&#x30F3; &#x30C4;&#x30FC;&#x30EB;&#x306E;&#x5F37;&#x5316;&#x306A;&#x3069; - IEBlog &#x65E5;&#x672C;&#x8A9E; - Site Home - MSDN Blogs</a></p><p>クラウドォォ上でシミュレートできるとか、どうやら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BE%C1%DB%A5%DE%A5%B7%A5%F3">仮想マシン</a>用のVMを配ったりしているらしい。Windows, Mac はもちろん <a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a> にも対応しているし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Virtualbox">Virtualbox</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/VMWare%20Fusion">VMWare Fusion</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/Parallels">Parallels</a> の3種類ともそれぞれのVMを配っている。IEのバージョンとOSのバージョンもかなり詳細においてある。ただし日本語のフォントがはいってないっぽいのでそれはあきらめるか、自前でフォントいれるか。自前でフォントいれられるかな?試してない。</p> <div class="section"> <h3>IE10 もよい</h3> <p>実機とまではいかなくても<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D0%A5%C3%A5%B0">デバッグ</a>ツールでIE10, 9, 8, 7 までは表示モードと互換表示とかそこらへんをカバーしてくれるので、それも使える。</p> </div> <div class="section"> <h3>はい</h3> <p>MS、やる気が出るとすごい。やる気がでないとIE6-8みたいになるけど。「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apple">Apple</a> は iOS で Mobile <a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a> でブラウザの進化を止める動機がある。第二のIE6が生まれる可能性がある」というのも頷ける。ジャスコかイオン出して商店街壊滅させて便利を存分に享受させても都合が悪くなれば撤退する、みたいな話にも通じる。</p> </div> atasatamatara 外部API使用でも安心してコードをかくための、mock をつかったテスト hatenablog://entry/11696248318753312506 2013-05-09T21:13:32+09:00 2013-05-09T21:13:32+09:00 Twitter や Facebook に限らず、外部APIを叩かなければならない場面は出てくる。ただでさえテストコードかけないと不安になるのに、外部APIの挙動にあわせてうまく連携しないといけないケースでテストコードがかけないのはかなりこわい。そういうとき、mock が使える。Mock - Mocking and Testing Library — Mock 1.0.1 documentation requests と mock を使ってみる - Twisted Mind python の mock ライブラリを使ってみる: Addicted To Indentation つかう テストコード… <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a> や <a class="keyword" href="http://d.hatena.ne.jp/keyword/Facebook">Facebook</a> に限らず、外部<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を叩かなければならない場面は出てくる。ただでさえテストコードかけないと不安になるのに、外部<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>の挙動にあわせてうまく連携しないといけないケースでテストコードがかけないのはかなりこわい。そういうとき、mock が使える。</p><p><a href="http://www.voidspace.org.uk/python/mock/index.html">Mock - Mocking and Testing Library &mdash; Mock 1.0.1 documentation</a><br /> <a href="http://voluntas.hatenablog.com/entry/20111124/1322069748">requests &#x3068; mock &#x3092;&#x4F7F;&#x3063;&#x3066;&#x307F;&#x308B; - Twisted Mind</a><br /> <a href="http://torufurukawa.blogspot.jp/2011/11/python-mock.html">python &#x306E; mock &#x30E9;&#x30A4;&#x30D6;&#x30E9;&#x30EA;&#x3092;&#x4F7F;&#x3063;&#x3066;&#x307F;&#x308B;: Addicted To Indentation</a></p> <div class="section"> <h3>つかう</h3> <p>テストコードとかテストケースの話になるとモヒカンが飛んできそうなので<a href="#f1" name="fn1" title="指摘自体は受けたいけど、前置きしておかないとちょっとこわい">*1</a>すごくざっくりした理解で書いておく。</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synPreProc">from</span> mock <span class="synPreProc">import</span> Mock <span class="synComment"># モックをつくる</span> m = Mock() <span class="synComment"># m を呼び出すと必ず &quot;hogemoge&quot; がかえってくるようにする</span> m.return_value = <span class="synConstant">&quot;hogemoge&quot;</span> <span class="synComment"># テストする</span> <span class="synStatement">assert</span> m == <span class="synConstant">&quot;hogemoge&quot;</span> </pre><p>実際テストコードの記述は unittest や Django の unittest、テストランナーとしては nose なり pytest なり Django test コマンドで走らせたりする。</p> </div> <div class="section"> <h3>もうちょっと使う</h3> <p>自分が実装している関数ではなく、外部ライブラリに依存している場合、それの挙動を差し替える</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synPreProc">from</span> mock <span class="synPreProc">import</span> patch <span class="synPreProc">import</span> some_method <span class="synComment"># context_manager で呼び出す</span> <span class="synPreProc">import</span> mymodule <span class="synStatement">with</span> patch(<span class="synConstant">&quot;mymodule.coooooool_script&quot;</span>) <span class="synStatement">as</span> m: m.return_value = <span class="synConstant">&quot;it's cool&quot;</span> self.assertEqual(some_method(), m) <span class="synComment"># デコレータで呼び出す</span> <span class="synStatement">class</span> <span class="synIdentifier">Tests</span>(TestCase): <span class="synPreProc">@</span><span class="synIdentifier">patch</span>(return_value=<span class="synConstant">&quot;it's cool&quot;</span>) <span class="synStatement">def</span> <span class="synIdentifier">coooooooool_script_vaild</span>(self, m): self.assertEqual(some_method(), m) <span class="synComment"># 例外を起こしたい</span> <span class="synStatement">def</span> <span class="synIdentifier">coooooooool_script_vaild_valid</span>(self) <span class="synStatement">with</span> patch(<span class="synConstant">&quot;mymodule.coooooool_script&quot;</span>) <span class="synStatement">as</span> m: m.side_effect = CoooolError() <span class="synStatement">with</span> assertRaises(CoooolError): some_method() <span class="synComment"># インスタンスメソッドを書き換えたい</span> <span class="synComment"># なのでクラスもモックにする必要がある</span> <span class="synPreProc">import</span> MyCoooooolClass patch(<span class="synConstant">'MyCoooooolClass'</span>) <span class="synStatement">def</span> <span class="synIdentifier">coooooooool_script_vaild_valid_valid</span>(self, mock_class): <span class="synStatement">with</span> patch(<span class="synConstant">&quot;mycoooooolclass.coooooool_script&quot;</span>) <span class="synStatement">as</span> m: instance = mock_class.return_value instance.soooomeeeeeeeethod.return_value = <span class="synConstant">&quot;hai&quot;</span> self.assertEqual(instance.soooomeeeeeeeethod, <span class="synConstant">&quot;hai&quot;</span>) </pre><p>いろいろ記述方法やつかいかた、あるいはテストコード自体に疑問がわいたりもするけど、参考資料みながらこんな感じでかいていた。もっといいやりかたがあるとうれしい。</p> </div> <div class="section"> <h3>まあ</h3> <p>しかし「モック便利でなんでもできるけどモック職人になったらそれはそれで考えたほうがいい」というのもあるし、テストしやすい設計だいじだなー。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">指摘自体は受けたいけど、前置きしておかないとちょっとこわい</span></p> </div> atasatamatara mercurial で一部の変更をコミットする hatenablog://entry/11696248318753280059 2013-05-08T19:29:39+09:00 2013-05-08T19:29:39+09:00 ある機能やバグを修正するとき、ついでにまとめて修正してしまうとかある。そのとき、まとめて修正してしまったのは仕方ないけれどコミットとしては別にしておきたいときに使う。git で言うと add するタイミングや add -p 的なこと。 結論 hg record 拡張つかおう 参考::1ファイルの変更の一部のみをコミットする #Mercurial - Qiita [キータ] 参考::いつの間にかhg recordのハンクが最少単位になっていた - 日々是鍛錬 導入 .hgrc に追記 [extension] record = つかう あんまり考えなくても対話的に聞いてくれるので楽 hg reco… <p>ある機能やバグを修正するとき、ついでにまとめて修正してしまうとかある。そのとき、まとめて修正してしまったのは仕方ないけれどコミットとしては別にしておきたいときに使う。git で言うと add するタイミングや add -p 的なこと。</p> <div class="section"> <h3>結論</h3> <p>hg record 拡張つかおう<br /> 参考::<a href="http://qiita.com/items/ddf15cf0bf2f8ce358db">1&#x30D5;&#x30A1;&#x30A4;&#x30EB;&#x306E;&#x5909;&#x66F4;&#x306E;&#x4E00;&#x90E8;&#x306E;&#x307F;&#x3092;&#x30B3;&#x30DF;&#x30C3;&#x30C8;&#x3059;&#x308B; #Mercurial - Qiita [&#x30AD;&#x30FC;&#x30BF;]</a><br /> 参考::<a href="http://yoppi.hatenablog.com/entry/20111210/record_extention_became_clever">&#x3044;&#x3064;&#x306E;&#x9593;&#x306B;&#x304B;hg record&#x306E;&#x30CF;&#x30F3;&#x30AF;&#x304C;&#x6700;&#x5C11;&#x5358;&#x4F4D;&#x306B;&#x306A;&#x3063;&#x3066;&#x3044;&#x305F; - &#x65E5;&#x3005;&#x662F;&#x935B;&#x932C;</a></p> </div> <div class="section"> <h3>導入</h3> <p>.hgrc に追記</p> <pre class="code lang-cfg" data-lang="cfg" data-unlink><span class="synType">[extension]</span> <span class="synStatement">record </span>= </pre> </div> <div class="section"> <h3>つかう</h3> <p>あんまり考えなくても対話的に聞いてくれるので楽</p> <pre class="code lang-sh" data-lang="sh" data-unlink>hg record </pre><p>とりあえず今回はまとめてしまったものを y/n で選択してコミットを分けた。なんだか選択肢はいろいろあるけど、とりあえず y/n で選択、qで強制終了だけつかった。</p> </div> <div class="section"> <h3>まあ</h3> <p>かなり使い勝手が良い。ありがたい</p> </div> atasatamatara Django のダミーデータを大量投入するスクリプトを対話環境に対応させるシェルスクリプトで自動化した hatenablog://entry/11696248318752937399 2013-04-30T20:35:41+09:00 2013-04-30T20:35:41+09:00 やっぱりだるかった Django アプリのダミーデータを大量投入するスクリプトをかく - AtAsAtAmAtArAのをコピペ運用でもよかったけど、コピペ条件かわったりいちいちもうそういうのだるかったので、やっぱりデータを初期化するところまで自動化することにした。 expect をつかった Django ORM から生成したいからスクリプトは変えたくない。でも余計な python ライブラリは気持ち的にあまりいれたくない。python manage.py sql... とかいろいろあるけど、どうもつかえなさそうだ。python manage.py shell は python -c みたいに直… <div class="section"> <h3>やっぱりだるかった</h3> <p><a href="http://atasatamatara.hatenablog.jp/entry/2013/04/04/210323">Django &#x30A2;&#x30D7;&#x30EA;&#x306E;&#x30C0;&#x30DF;&#x30FC;&#x30C7;&#x30FC;&#x30BF;&#x3092;&#x5927;&#x91CF;&#x6295;&#x5165;&#x3059;&#x308B;&#x30B9;&#x30AF;&#x30EA;&#x30D7;&#x30C8;&#x3092;&#x304B;&#x304F; - AtAsAtAmAtArA</a>のをコピペ運用でもよかったけど、コピペ条件かわったりいちいちもうそういうのだるかったので、やっぱりデータを初期化するところまで自動化することにした。</p> </div> <div class="section"> <h3>expect をつかった</h3> <p>Django ORM から生成したいからスクリプトは変えたくない。でも余計な <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> ライブラリは気持ち的にあまりいれたくない。<a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> manage.py <a class="keyword" href="http://d.hatena.ne.jp/keyword/sql">sql</a>... とかいろいろあるけど、どうもつかえなさそうだ。<a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> manage.py shell は <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> -c みたいに直接実行ができない。対話シェルになるのは必然っぽい。じゃあどうしよう。</p><p>対話シェルになってしまうものをむりやりどうにかできないか探したらあっさり expect というのが見つかった。パターンマッチさせてコマンドを実行させてしまう。すごい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a> や <a class="keyword" href="http://d.hatena.ne.jp/keyword/rsync">rsync</a> とか useradd とかで使うのを想定しているみたいだけど、これはいけそうだ。</p> <pre class="code lang-sh" data-lang="sh" data-unlink>sudo apt-get <span class="synStatement">install</span> expect </pre><p>参考::<a href="http://at-aka.blogspot.jp/2009/02/expect-passwd.html">clmemo@aka: Expect &#x30B3;&#x30DE;&#x30F3;&#x30C9;&#x3067; passwd &#x5909;&#x66F4;</a><br /> 参考::<a href="http://arakanoj.com/linux-なら-expect-でコマンドを自動化しよう-1135.html">Linux &#x306A;&#x3089; expect &#x3067;&#x30B3;&#x30DE;&#x30F3;&#x30C9;&#x3092;&#x81EA;&#x52D5;&#x5316;&#x3057;&#x3088;&#x3046; | &#x6E29;&#x6545;&#x77E5;&#x65B0; linux&#x5B9F;&#x8DF5;&#x8B1B;&#x5EA7;</a></p> </div> <div class="section"> <h3>パターンマッチは --plain でやった</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> にも pexpect なるパッケージもあるけど、あんまり今回はいれたくなかったのでどうにか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%A7%A5%EB%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">シェルスクリプト</a>でやりたい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> manage.py shell だとどうしても ipython か bpython が選択されてしまう。そのとき "In [1]: "のマッチでよくわからないがコケる。こまった。</p><p>結局 <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> manage.py shell は --plain で ipython とか使わないプレーンな標準の対話シェルが指定できるから、それをやった。</p> </div> <div class="section"> <h3>成果</h3> <p>だいぶゴリ押し感ある</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment">#!/bin/bash</span> current_dir <span class="synStatement">=</span> ... target_dir <span class="synStatement">=</span> ... cp <span class="synPreProc">$current_dir</span>/make_dummy_data.py <span class="synPreProc">$terget_dir</span> <span class="synStatement">rm</span> ... python manage.py syncdb ... python manage.py migrate ... expect <span class="synSpecial">-c</span> <span class="synStatement">&quot;</span> <span class="synConstant">set timeout 1</span> <span class="synConstant">expect '&gt;&gt;&gt;'</span> <span class="synConstant">send </span><span class="synStatement">&quot;</span>import make_dummy_data\n<span class="synStatement">&quot;</span> <span class="synConstant">expect '&gt;&gt;&gt;'</span> <span class="synConstant">send </span><span class="synStatement">&quot;</span>make_dummy_data.main<span class="synPreProc">()</span>\n<span class="synStatement">&quot;</span> <span class="synConstant">expect '&gt;&gt;&gt;'</span> <span class="synConstant">send </span><span class="synStatement">&quot;exit</span><span class="synPreProc">()</span>\n<span class="synStatement">&quot;</span> <span class="synConstant">interactive</span> <span class="synStatement">&quot;</span> </pre><p>send したら改行コードを忘れずに。エスケープはてきとう。 set timeout でタイムアウト指定できるから -1 とかにもしたけど、なんかだめっぽかったからてきとうに小さい値を入れておいた。</p> </div> <div class="section"> <h3>まあ</h3> <p>よかったんだが、実は echo でよかったらしい</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synStatement">echo</span><span class="synConstant"> </span><span class="synStatement">&quot;</span><span class="synConstant">print(1)</span><span class="synStatement">&quot;</span><span class="synConstant"> </span>| python manage.py shell </pre><p>なにをやっていたのだか……</p> </div> atasatamatara Facebook いいねボタンの挙動を localhost で検証する hatenablog://entry/11696248318752777694 2013-04-25T20:05:21+09:00 2013-04-25T20:05:21+09:00 Facebook app 登録 まあしましょう ドメイン設定が必要 app の設定で localhost とかだとなんかだめっぽかったので以下を参考にした localhost環境で、Facebook のJavaScript APIでOAuth認証をする - Goodpic testapp.comこの場合 Mac がローカルだからいいけど、自分の場合開発用の Ubuntu Server でやってるので Mac 側の hosts の設定は以下を参考にした。 VMware上で動くWebアプリにホスト側からアクセス | ゆーすけぶろぐ # 開発用のVMのアドレス 192.168.56.101 loca… <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/Facebook">Facebook</a> app 登録</h3> <p>まあしましょう</p> </div> <div class="section"> <h3>ドメイン設定が必要</h3> <p>app の設定で <a class="keyword" href="http://d.hatena.ne.jp/keyword/localhost">localhost</a> とかだとなんかだめっぽかったので以下を参考にした<br /> <a href="http://www.goodpic.com/mt/archives2/2012/01/localhost-facebook-javascript-api.html">localhost&#x74B0;&#x5883;&#x3067;&#x3001;Facebook &#x306E;JavaScript API&#x3067;OAuth&#x8A8D;&#x8A3C;&#x3092;&#x3059;&#x308B; - Goodpic</a></p> <pre class="code" data-unlink>testapp.com</pre><p>この場合 Mac がローカルだからいいけど、自分の場合開発用の <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a> Server でやってるので Mac 側の hosts の設定は以下を参考にした。<br /> <a href="http://yusukezzz.net/blog/archives/1688">VMware&#x4E0A;&#x3067;&#x52D5;&#x304F;Web&#x30A2;&#x30D7;&#x30EA;&#x306B;&#x30DB;&#x30B9;&#x30C8;&#x5074;&#x304B;&#x3089;&#x30A2;&#x30AF;&#x30BB;&#x30B9; | &#x3086;&#x30FC;&#x3059;&#x3051;&#x3076;&#x308D;&#x3050;</a></p> <pre class="code" data-unlink><span class="synComment"># 開発用のVMのアドレス</span> 192.168.56.101 local.testapp.com </pre><p>そうえば hosts って設定してよしなにしたことなかった。</p> </div> <div class="section"> <h3>検証する</h3> <p>FQL(<a class="keyword" href="http://d.hatena.ne.jp/keyword/Facebook">Facebook</a> Query Language) を飛ばして確認する。使用ライブラリは (<a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a>)<a class="keyword" href="http://d.hatena.ne.jp/keyword/facebook">facebook</a>-<a class="keyword" href="http://d.hatena.ne.jp/keyword/sdk">sdk</a></p> <pre class="code" data-unlink>&gt;&gt;&gt; <span class="synPreProc">import</span> facebook &gt;&gt;&gt; g = facebook.GraphAPI(<span class="synConstant">'token'</span>) &gt;&gt;&gt; g &lt;facebook.GraphAPI <span class="synIdentifier">object</span> &gt; <span class="synComment"># Like する前</span> &gt;&gt;&gt; g.fql(<span class="synConstant">'select like_count from link_stat where url=&quot;testapp.com&quot;'</span>) [{<span class="synConstant">u'like_count'</span>: <span class="synConstant">0</span>}] <span class="synComment"># Like したあと</span> &gt;&gt;&gt; g.fql(<span class="synConstant">'select like_count from link_stat where url=&quot;testapp.com&quot;'</span>) [{<span class="synConstant">u'like_count'</span>: <span class="synConstant">1</span>}] </pre><p>どうやら機能していることがわかる</p> </div> <div class="section"> <h3>まあ</h3> <p>はい</p> </div> atasatamatara Django でメールを送信と確認 hatenablog://entry/11696248318752683459 2013-04-23T21:01:01+09:00 2013-04-23T21:01:01+09:00 メールを送信する。Python 標準モジュールやライブラリにもありそうだけど、Django 組み込みであるのでそれを利用する。 日本語1.4::メールの送信 — Django 1.4 documentation つかう ドキュメントのままです from django.core.mail import send_mail send_mail('Subject here', 'Here is the message.', 'from@example.com', ['to@example.com'], fail_silently=False) # もうちょっとつかいまわしやすくする message … <p>メールを送信する。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> 標準モジュールやライブラリにもありそうだけど、Django 組み込みであるのでそれを利用する。<br /> 日本語1.4::<a href="http://docs.djangoproject.jp/en/latest/topics/email.html">&#x30E1;&#x30FC;&#x30EB;&#x306E;&#x9001;&#x4FE1; &mdash; Django 1.4 documentation</a></p> <div class="section"> <h3>つかう</h3> <p>ドキュメントのままです</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synPreProc">from</span> django.core.mail <span class="synPreProc">import</span> send_mail send_mail(<span class="synConstant">'Subject here'</span>, <span class="synConstant">'Here is the message.'</span>, <span class="synConstant">'from@example.com'</span>, [<span class="synConstant">'to@example.com'</span>], fail_silently=<span class="synIdentifier">False</span>) <span class="synComment"># もうちょっとつかいまわしやすくする</span> message = message subject = subject <span class="synComment"># to 部分はリストかタプルで指定</span> email_from = <span class="synConstant">&quot;atas@hoge.com&quot;</span> email_to = (<span class="synConstant">&quot;noreply@hoge.com&quot;</span>,) send_mail(subject, message, email_from, email_to) </pre><p>メールサーバーはとりあえず <a class="keyword" href="http://d.hatena.ne.jp/keyword/postfix">postfix</a> をつかった</p> <pre class="code lang-sh" data-lang="sh" data-unlink>sudo apt-get <span class="synStatement">install</span> postfix sudo /etc/init.d/postfix <span class="synStatement">start</span> </pre><p>とどきます</p> </div> <div class="section"> <h3>ダミーサーバーをたてる</h3> <p>いちいち全部自分宛にやるのもうっとおしいのでなんかないかな、と思ったら <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> の smtpd モジュールで DebuggingServer なるものがあるらしくて、そのままつかった</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synComment"># sudo しないと動かなかった。権限の問題?</span> sudo python -m smtpd -n -c DebuggingServer localhost:<span class="synConstant">25</span> </pre><p>なんかダミーサーバーがうごいていないと思ったら、<a class="keyword" href="http://d.hatena.ne.jp/keyword/postfix">postfix</a> が port 25 で動いてたので止めたらよかった</p> <pre class="code lang-sh" data-lang="sh" data-unlink>sudo /etc/init.d/postfix <span class="synStatement">stop</span> </pre><p>内容はこんな感じ</p> <pre class="code lang-sh" data-lang="sh" data-unlink> ---------- MESSAGE FOLLOWS <span class="synSpecial">----------</span> Content-Type: text/plain; <span class="synIdentifier">charset</span>=<span class="synStatement">&quot;</span><span class="synConstant">utf-8</span><span class="synStatement">&quot;</span> MIME-Version: <span class="synConstant">1</span>.<span class="synConstant">0</span> Content-Transfer-Encoding: 8bit Subject: some message From: noreply@hoge.com To: atas@hoge.com Date: Wed, <span class="synConstant">17</span> Apr <span class="synConstant">2001</span> <span class="synConstant">06</span>:<span class="synConstant">37</span>:<span class="synConstant">39</span> <span class="synConstant">-0000</span> Message-ID: <span class="synStatement">&lt;</span><span class="synConstant">20130417063739</span>.<span class="synConstant">10658</span>.<span class="synConstant">62373</span>@dev<span class="synStatement">&gt;</span> X-Peer: <span class="synConstant">127</span>.<span class="synConstant">0</span>.<span class="synConstant">0</span>.<span class="synConstant">1</span> 高円寺<span class="synConstant">5</span>.<span class="synConstant">5</span>万円徒歩<span class="synConstant">10</span>分東向き部屋一人暮らし情報ください ------------ END MESSAGE <span class="synSpecial">------------</span> </pre><p>ちなみに -m はモジュール、-c はコマンドってのはわかったけど -n ってなんだろう。</p> </div> <div class="section"> <h3>まあ</h3> <p>はい</p> </div> atasatamatara grep/ack/ag でのエスケープがわからないなら直接文字列リテラル渡せばいいじゃない hatenablog://entry/11696248318752658425 2013-04-22T20:03:29+09:00 2013-04-23T08:27:49+09:00 適当にエスケープしてメタ文字消して置換しようとしたけど、正直よくわからなかった。たとえばこういうもの Obj.objects.create(**kwargs) こういうとき愚直に「. をエスケープして……あれ()ってクオートで囲むの……あれ……」とかやってた 別に単純な文字列のマッチでよかった そういうときには grep なら -F, ag なら -Q というオブションがある # grep grep -rF "Obj.objects.create(**kwargs)" ./ # ag ag -Q "Obj.objects.create(**kwargs)" あとは煮るなり焼くなり # -l で… <p>適当にエスケープしてメタ文字消して置換しようとしたけど、正直よくわからなかった。たとえばこういうもの</p> <pre class="code lang-python" data-lang="python" data-unlink>Obj.objects.create(**kwargs) </pre><p>こういうとき愚直に「. をエスケープして……あれ()ってクオートで囲むの……あれ……」とかやってた</p> <div class="section"> <h3>別に単純な文字列のマッチでよかった</h3> <p>そういうときには <a class="keyword" href="http://d.hatena.ne.jp/keyword/grep">grep</a> なら -F, ag なら -Q というオブションがある</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># grep</span> <span class="synStatement">grep</span> <span class="synSpecial">-rF</span> <span class="synStatement">&quot;</span><span class="synConstant">Obj.objects.create(**kwargs)</span><span class="synStatement">&quot;</span> ./ <span class="synComment"># ag</span> ag <span class="synSpecial">-Q</span> <span class="synStatement">&quot;</span><span class="synConstant">Obj.objects.create(**kwargs)</span><span class="synStatement">&quot;</span> </pre><p>あとは煮るなり焼くなり</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># -l でファイル出力して xrags で受け取る</span> ag <span class="synSpecial">-lQ</span> <span class="synStatement">&quot;</span><span class="synConstant">Obj.objects.create(**kwargs)</span><span class="synStatement">&quot;</span> | xargs <span class="synStatement">sed</span> <span class="synSpecial">-i</span> <span class="synStatement">&quot;</span><span class="synConstant">s/Obj\.objects\.create(**kwargs)/oyaoya/g</span><span class="synStatement">&quot;</span> </pre> </div> <div class="section"> <h3>はい</h3> <p>真面目に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>で必要ならいいけど、単純な文字列置換したいだけならこの方が楽。ほんとうは <a class="keyword" href="http://d.hatena.ne.jp/keyword/sed">sed</a> 側も<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>じゃなくて直接置換できるといいんだけど、 d で消して a で追加とかなのかな?ちょっと調べたけどわからなかった。</p> </div> atasatamatara Django のコマンドを作って定期的に実行する hatenablog://entry/11696248318752509093 2013-04-17T20:27:00+09:00 2013-04-17T20:27:00+09:00 なんてことはないが、ちょっとハマったのでメモ 流れ Django の python manage.py some_command をつくる crontab に登録する それだけなんだけど、復習も込めて Django でカスタムコマンドをつくる 単純なスクリプトならそのまま Python のスクリプトとしてつかえばいいとおもうけど、 Django のコマンドであること、またそれらのモデルとかと連携したり、まああと意味合い的にそっちにもたせたいとかあるとき、コマンドを自作できる。 日本語 1.0::アクションを自作する — Django v1.0 documentation 英語 1.5::Wri… <p>なんてことはないが、ちょっとハマったのでメモ</p> <div class="section"> <h3>流れ</h3> <ul> <li>Django の <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> manage.py some_command をつくる</li> <li>crontab に登録する</li> </ul><p>それだけなんだけど、復習も込めて</p> </div> <div class="section"> <h3>Django でカスタムコマンドをつくる</h3> <p>単純なスクリプトならそのまま <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> のスクリプトとしてつかえばいいとおもうけど、 Django のコマンドであること、またそれらのモデルとかと連携したり、まああと意味合い的にそっちにもたせたいとかあるとき、コマンドを自作できる。<br /> 日本語 1.0::<a href="http://www.djangoproject.jp/doc/ja/1.0/howto/custom-management-commands.html">&#x30A2;&#x30AF;&#x30B7;&#x30E7;&#x30F3;&#x3092;&#x81EA;&#x4F5C;&#x3059;&#x308B; &mdash; Django v1.0 documentation</a><br /> 英語 1.5::<a href="https://docs.djangoproject.com/en/1.5/howto/custom-management-commands/">Writing custom django-admin commands | Django documentation | Django</a><br /> 英語の最新版のほうがわかりやすい。</p> <div class="section"> <h4>階層をつくる</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>/プロジェクト/アプリ/ とツリー構造があるとき、INSTALLED_APPS に通っているパスで management/commands をつくる。<a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> なので __init__.py も忘れずに。</p> </div> <div class="section"> <h4>BaseCommand クラスを継承したクラスをつくる</h4> <p>例だと class Command(BaseCommand) としてつくってる。クラス変数にオプションやらなんやらを設定できる。引数は optparse ベースで現状 <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> 2.7 だから argparse なんじゃないのとおもったけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/PyPi">PyPi</a> にはそれっぽいライブラリをつくってくれている人はいる。</p> </div> <div class="section"> <h4>実際の処理をかく</h4> <p>自分の場合は def handle(self, *args, **options) は main と同じような扱いにして、あとは関数に分けた。logger とかそういうバッチ処理系のなんかはよしなにした。</p> </div> <div class="section"> <h4>動かす</h4> <p>ファイル名が実行コマンドになっている(クラス名ではない) ので <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> manage.py some_command で実行できる</p> <pre class="code" data-unlink>pyhton manage.py some_command</pre> </div> </div> <div class="section"> <h3>crontab で動かす</h3> <p>定期的に実行するなら crontab はまあつかう。で、登録する。それはいいが、2つハマった。</p> <div class="section"> <h4>実行ユーザーの登録</h4> <p>実運営的にどうするかはわからないけど、実行ユーザーを管理したい場合は crontab -u user -e で登録できる。だけど <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a> だと sudo する必用があったっぽくて、root 権限でしか動かせないかと思ってた。そんなことはなかった。</p> <pre class="code" data-unlink>sudo crontab <span class="synSpecial">-u</span> atas <span class="synSpecial">-e</span> </pre><p>でよい</p> </div> <div class="section"> <h4>virtualenv 環境</h4> <p>普段 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> 関係の開発だと virtualenv(pyvenv) は必須だと思うけど、シェルから簡単に叩ける virtualenvwrapper を使っていた。でも、cron の登録では workon など virtualenvwrapper のコマンドは叩けないよね、ってところで少しハマってた。なので直接 virtualenv を activate すればよい</p> <pre class="code" data-unlink><span class="synStatement">. </span>~/.virtualenv/dev/bin/activate </pre> </div> </div> <div class="section"> <h3>つなげる</h3> <p>こうなる</p> <pre class="code" data-unlink><span class="synComment"># m, h, d, w, m, command</span> <span class="synConstant">*</span><span class="synPreProc"> *</span><span class="synType"> *</span><span class="synConstant"> *</span><span class="synPreProc"> *</span> <span class="synStatement">. /home/atas/.virtualenv/dev/bin/activate &amp;&amp; cd /path/to/porject &amp;&amp; python mamage.py some_command</span> </pre><p>もうちょっとちゃんとやるなら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%A7%A5%EB%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">シェルスクリプト</a>にして</p> <pre class="code" data-unlink><span class="synComment">#!/bin/bash</span> <span class="synStatement">export</span><span class="synIdentifier"> DJANGO_SETTINGS_MODULE=</span>mysite.settings <span class="synStatement">. </span>/path/to/virtualenv/dev/bin/activate <span class="synStatement">cd</span> /path/to/src python manage.py some_command </pre><p>のほうがいいかもしれない</p> </div> <div class="section"> <h3>トラブルシューティング</h3> <p>Django のカスタムコマンドはつくれている前提で crontab での実行がどうなってるかがみえなかった</p> <ul> <li>登録っぽいことをかく</li> <li>ログは /var/log/syslog に出るらしい</li> <li>crontab の設定自体は /var/spool/crontab/... にあるらしい(が、実ファイルを直接触ることは基本しないらしい)</li> <li>tmux でペインを分けてログを監視する tail -f /var/log/syslog <ul> <li>ちなみに less で表示して shift f でも同じ事できるけど、圧倒的に普段は tail -f のほうがいい感じだった</li> </ul></li> <li>logger も動かしているのでそのファイルの状態も tail -f some.log してみる</li> <li>VM で開発しているのでたぶん大丈夫だけど時刻設定は date コマンドで確認する。1分を待つのが長い。</li> <li>ユーザーやなんやらでうごかなかったけど、結局はよく考えたら virtualenv 環境で環境のパスを実行ユーザーが見れないと困るよね<a href="#f1" name="fn1" title="この記事をかいたときPYTHONPATH だと思ってたけど違った">*1</a>、というようなところで解決</li> </ul> </div> <div class="section"> <h3>まあ</h3> <p>ある</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">この記事をかいたときPYTHONPATH だと思ってたけど違った</span></p> </div> atasatamatara Python の全角半角処理に zenhan が便利 hatenablog://entry/6435988827677199223 2013-04-15T20:19:55+09:00 2013-04-15T20:19:55+09:00 バリデーションとか検索とか だいたい全角半角でどうとか変換とかかませたりする。で、Python で有名なところだと zenhan というのがある。 導入 PyPi にある。うれしい。 pip install zenhan つかう 公式にもあるけど、ヘルプ見た感じでも難しくない import zenhan # バイト列 s = 'Foo' # unicode 型に変換 if isinstanc(s, str): s = s.decode('utf-8') # 全角から半角に変換 s_hankaku = zenhan.z2h(s) print(s_hankaku) # Foo いいですね 英数字だ… <div class="section"> <h3>バリデーションとか検索とか</h3> <p>だいたい全角半角でどうとか変換とかかませたりする。で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> で有名なところだと zenhan というのがある。</p> </div> <div class="section"> <h3>導入</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/PyPi">PyPi</a> にある。うれしい。</p> <pre class="code lang-sh" data-lang="sh" data-unlink>pip <span class="synStatement">install</span> zenhan </pre> </div> <div class="section"> <h3>つかう</h3> <p>公式にもあるけど、ヘルプ見た感じでも難しくない</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synPreProc">import</span> zenhan <span class="synComment"># バイト列</span> s = <span class="synConstant">'Foo'</span> <span class="synComment"># unicode 型に変換</span> <span class="synStatement">if</span> isinstanc(s, <span class="synIdentifier">str</span>): s = s.decode(<span class="synConstant">'utf-8'</span>) <span class="synComment"># 全角から半角に変換</span> s_hankaku = zenhan.z2h(s) <span class="synIdentifier">print</span>(s_hankaku) <span class="synComment"># Foo</span> </pre><p>いいですね</p><p></p> </div> <div class="section"> <h3>英数字だけ変換したい</h3> <p>ちょっとはまったのは、日本語部分は別にそのままでいいんだけど英数字だけ変換したいしたいということだった。オプション指定すればいいだけだった</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synIdentifier">help</span>(zenhan) FUNCTIONS h2z(text, mode=<span class="synConstant">7</span>, ignore=()) <span class="synComment"># function convert from HANKAKU to ZENKAKU</span> <span class="synComment"># argument and return: unicode string</span> z2h(text=<span class="synConstant">''</span>, mode=<span class="synConstant">7</span>, ignore=()) <span class="synComment"># function convert from ZENKAKU to HANKAKU</span> <span class="synComment"># argument and return: unicode string</span> DATA ALL = <span class="synConstant">7</span> ASCII = <span class="synConstant">1</span> DIGIT = <span class="synConstant">2</span> KANA = <span class="synConstant">4</span> __version__ = <span class="synConstant">'0.4'</span> VERSION <span class="synConstant">0.4</span> </pre><p>ということで、この場合 3 をしていてやったらうまくいった</p> </div> <div class="section"> <h3>はい</h3> <p>ありがたや</p> </div> atasatamatara tmux の起動時セッションを自動化する tmuxinator いれた hatenablog://entry/6435988827676822635 2013-04-05T21:04:52+09:00 2013-04-05T21:04:52+09:00 開発用 Ubuntu VM はスリープっぽい保存はするけど、ローカルの Mac は落とさないといけない。で、毎回 ssh でウィンドウやペインごとに ssh つないだりするのはだるい。ということで tmuxinator いれた。 導入 いろいろある。特に ruby の開発してないし、適当にシステムグローバルにいれた*1。 tmuxinatorで一瞬で開発環境を起動する #Ruby #AdventCalendar #tmux #開発環境 - Qiita # インストール gem install tmuxinator # .zshrc に設定 [[ -s ~/.tmuxinator/scripts… <p>開発用 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a> VM はスリープっぽい保存はするけど、ローカルの Mac は落とさないといけない。で、毎回 <a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a> でウィンドウやペインごとに <a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a> つないだりするのはだるい。ということで tmuxinator いれた。</p> <div class="section"> <h3>導入</h3> <p>いろいろある。特に <a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a> の開発してないし、適当にシステムグローバルにいれた<a href="#f1" name="fn1" title="まあ ruby で開発することがあったら rbenv を使うだろう。tmuxinator は rvm を想定しているっぽいのがあるけど">*1</a>。<br /> <a href="http://qiita.com/items/869b00fdde27c2225989">tmuxinator&#x3067;&#x4E00;&#x77AC;&#x3067;&#x958B;&#x767A;&#x74B0;&#x5883;&#x3092;&#x8D77;&#x52D5;&#x3059;&#x308B; #Ruby #AdventCalendar #tmux #&#x958B;&#x767A;&#x74B0;&#x5883; - Qiita</a></p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># インストール</span> gem <span class="synStatement">install</span> tmuxinator <span class="synComment"># .zshrc に設定</span> <span class="synSpecial">[[</span> <span class="synStatement">-s</span> ~/.tmuxinator/scripts/tmuxinator <span class="synSpecial">]]</span> &amp;&amp; <span class="synStatement">source</span> ~/.tmuxinator/scripts/tmuxinator </pre><p>で、つくる。ひな形やサンプルがあるのでだいたい簡単にできる。</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># デフォルトの alias</span> mux new my_project </pre><p>設定はこんなかんじにした。コマンドの連結がシェルの文法なのか独特の yml なのか、それともできないのかはよくわからない。実際動いてない。けどまあ、とりあえず複数 <a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a> でつなぐだけできるからいい。</p> <pre class="code lang-yaml" data-lang="yaml" data-unlink><span class="synComment"># ~/.tmuxinator/my_proj.yml</span> <span class="synComment"># you can make as many tabs as you wish...</span> <span class="synIdentifier">project_name</span><span class="synSpecial">:</span> my_proj <span class="synIdentifier">project_root</span><span class="synSpecial">:</span> ~/ <span class="synIdentifier">socket_name</span><span class="synSpecial">:</span> <span class="synIdentifier">tabs</span><span class="synSpecial">:</span> <span class="synStatement">-</span> <span class="synIdentifier">VMvim</span><span class="synSpecial">:</span> ssh dev <span class="synStatement">-</span> <span class="synIdentifier">VMterm</span><span class="synSpecial">:</span> <span class="synIdentifier">layout</span><span class="synSpecial">:</span> main<span class="synStatement">-</span>vertical <span class="synIdentifier">panes</span><span class="synSpecial">:</span> <span class="synStatement">-</span> ssh dev <span class="synStatement">-</span> ssh dev <span class="synStatement">-</span> ssh dev <span class="synStatement">-</span> <span class="synIdentifier">my</span><span class="synSpecial">:</span> cd ~/work </pre><p>これだけなら簡単</p> </div> <div class="section"> <h3>256 色対応</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> で 256 color 対応しようとすると「ターミナルソフト」「シェル」「screen/tmux」「<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>」のすべてが対応していないと色が反映されない。で、いつもは tmux -2 で起動してたけど、mux を通すとできない。alias tmux = 'tmux -2' したりとかしたけど、結局以下に至った</p> <ul> <li>iTerm2 のターミナル設定を xterm-256color</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> は t_co=256 してある</li> <li>.tmux.conf で set-option -g default-terminal screen-256color</li> </ul><p>ちょっとつまづたいのは、xterm-256color ってターミナルの設定してるのに tmux 側では screen-256color なんだね。とか。そういうあたり。あとは github の issue あたりをみて cli_args で -2 とか設定するとかしてたけど、いらなかった。</p> </div> <div class="section"> <h3>まあ</h3> <p>自動化はよい</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">まあ <a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a> で開発することがあったら rbenv を使うだろう。tmuxinator は rvm を想定しているっぽいのがあるけど</span></p> </div> atasatamatara Django アプリのダミーデータを大量投入するスクリプトをかく hatenablog://entry/6435988827676791670 2013-04-04T21:03:23+09:00 2013-04-10T19:47:05+09:00 モデルのフィールドが変わったり名前変わったりしそうだし、開発初期だと sqlite でサクっとつくって壊したりする。というときでも、とりあえずサイトを動かしたりするためになんらかのダミーデータを大量投入する必要はある。で、つくってたりした。データ量としては10モデル x 10 とかつくれればよかったから多くはないけど、外部キーの組み合わせでよしなにやる必要があるので結果的にはとりあえず50個とか200個とかの単位でつくった。 人に聞いた いろいろ python manage.py shell で for でぶんまわす Emacs あたりで生 SQL かいてコピペする むしろ Emacs からそ… <p>モデルのフィールドが変わったり名前変わったりしそうだし、開発初期だと <a class="keyword" href="http://d.hatena.ne.jp/keyword/sqlite">sqlite</a> でサクっとつくって壊したりする。というときでも、とりあえずサイトを動かしたりするためになんらかのダミーデータを大量投入する必要はある。で、つくってたりした。</p><p>データ量としては10モデル x 10 とかつくれればよかったから多くはないけど、外部キーの組み合わせでよしなにやる必要があるので結果的にはとりあえず50個とか200個とかの単位でつくった。</p> <div class="section"> <h3>人に聞いた</h3> <p>いろいろ</p> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> manage.py shell で for でぶんまわす</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a> あたりで生 <a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a> かいてコピペする</li> <li>むしろ <a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a> からそのまま流す</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/mysql">mysql</a> workbench なるものがつかいやすいらしい</li> </ul><p>とかなんかまあなんかいろいろあったけど、とりあえずまだ <a class="keyword" href="http://d.hatena.ne.jp/keyword/sqlite">sqlite</a> だしまあ for でぶんまわした。生<a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a>をかくのはだるそうだし、ORM であわせたほうが楽っぽい気がしたし。</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synPreProc">from</span> django.utils.timezone <span class="synPreProc">import</span> now <span class="synPreProc">from</span> myproj.models <span class="synPreProc">import</span> MyModel <span class="synStatement">for</span> i <span class="synStatement">in</span> <span class="synIdentifier">xrange</span>(<span class="synConstant">1</span>, <span class="synConstant">50</span>): MyModel.<span class="synIdentifier">object</span>.create(name=<span class="synConstant">&quot;name{0}&quot;</span>.<span class="synIdentifier">format</span>(i), create_time=now()) </pre><p>まあこんな感じでゴリゴリ連番でつくっていった</p> </div> <div class="section"> <h3>のはいいけど</h3> <p>最初の一回はどうにか1時間くらいでつくったのはいいけど、モデルかわったり、外部キーでいろいろつくらないといけなかったからやっぱりスクリプトにした。やってることはだいたい上記なんだけど、どうしたらラクにできるかと。</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> のスクリプトにすればいいだけだった</h3> <p>そりゃそうだったんだが、要は make_<a class="keyword" href="http://d.hatena.ne.jp/keyword/sql">sql</a> とか作って <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> manage.py shell の中で import make_<a class="keyword" href="http://d.hatena.ne.jp/keyword/sql">sql</a> make_<a class="keyword" href="http://d.hatena.ne.jp/keyword/sql">sql</a>.main() とかすればよかっただけだった。以下はサンプル。</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synComment"># coding: utf-8</span> <span class="synStatement">if</span> __name__ == <span class="synConstant">'__main__'</span>: main() <span class="synStatement">def</span> <span class="synIdentifier">main</span>(): make_user() make_author() make_book() <span class="synStatement">def</span> <span class="synIdentifier">make_user</span>(): <span class="synStatement">for</span> i <span class="synStatement">in</span> <span class="synIdentifier">xrange</span>(<span class="synConstant">1</span>, <span class="synConstant">30</span>): User.objects.create( name=<span class="synConstant">&quot;name{0}&quot;</span>.<span class="synIdentifier">format</span>(i), email=<span class="synConstant">&quot;email{0}@email.com&quot;</span>.<span class="synIdentifier">format</span>(i), is_delete=<span class="synIdentifier">False</span>) <span class="synComment"># あとは外部キーとかたくさんコピペしながら条件付けしてつくっていく</span> ... </pre><pre class="code lang-python" data-lang="python" data-unlink><span class="synComment"># django でのシェルにはいって</span> python manage.py shell <span class="synComment"># インポートして</span> <span class="synPreProc">import</span> make_sql <span class="synComment"># 流す</span> make_sql.main() </pre> </div> <div class="section"> <h3>まあ</h3> <p>こういう作業はわりと嫌いじゃない。もっと言えば<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%A7%A5%EB%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">シェルスクリプト</a>にしてからこの <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> のスクリプト流しらもっとらくだけど、まあそこまではしなくていいかなってところにいる。</p> </div> atasatamatara Django でページング hatenablog://entry/6435988827676763406 2013-04-03T21:14:54+09:00 2013-04-03T21:14:54+09:00 よくある話、ページングしたかった。で、実際そういう機能がある。前は djang-pagination っていうのをつかったことがあったけど 1.3 くらいから使えなくなったとか、また、まあ別にそんなに難しい話でもなさそうだったので普通にフレームワークの機能で実装した。日本語 1.0::ペジネータ (paginator) — Django v1.0 documentation 公式 1.5::Pagination | Django documentation | Django最初から英語でみてたけど、英語のほうがサンプルコードが充実していてよい。 概要 Paginator クラスにクエリセットと… <p>よくある話、ページングしたかった。で、実際そういう機能がある。前は djang-pagination っていうのをつかったことがあったけど 1.3 くらいから使えなくなったとか、また、まあ別にそんなに難しい話でもなさそうだったので普通に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EC%A1%BC%A5%E0%A5%EF%A1%BC%A5%AF">フレームワーク</a>の機能で実装した。</p><p>日本語 1.0::<a href="http://www.djangoproject.jp/doc/ja/1.0/topics/pagination.html#topics-pagination">&#x30DA;&#x30B8;&#x30CD;&#x30FC;&#x30BF; (paginator) &mdash; Django v1.0 documentation</a><br /> 公式 1.5::<a href="https://docs.djangoproject.com/en/1.5/topics/pagination/">Pagination | Django documentation | Django</a></p><p>最初から英語でみてたけど、英語のほうがサンプルコードが充実していてよい。</p> <div class="section"> <h3>概要</h3> <ul> <li>Paginator クラスにクエリセットとページ指定をして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>にして</li> <li>paginator.page(page)で実際のページを表示させる</li> </ul><p>基本はこれだけ。</p> <div class="section"> <h4>ちなみに</h4> <p>以下にかくことをそれっぽくいい感じにお手軽に提供してくれるのが django.views.generic.ListView (class base view) ですね</p> </div> </div> <div class="section"> <h3>サンプル</h3> <p>公式にあるサンプルに自分の理解でコメントをつける。</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synComment"># 必用なものをとりこむ</span> <span class="synPreProc">from</span> django.core.paginator <span class="synPreProc">import</span> Paginator, EmptyPage, PageNotAnInteger <span class="synStatement">def</span> <span class="synIdentifier">listing</span>(request): <span class="synComment"># ページング対象にしたいオブジェクトをすべて取得しておく</span> contact_list = Contacts.objects.<span class="synIdentifier">all</span>() <span class="synComment"># Paginator でインスタンスにする。この場合 25 件づつページングする</span> paginator = Paginator(contact_list, <span class="synConstant">25</span>) <span class="synComment"># クエリストリングで page の値を受け取る</span> page = request.GET.get(<span class="synConstant">'page'</span>) <span class="synStatement">try</span>: contacts = paginator.page(page) <span class="synStatement">except</span> PageNotAnInteger: <span class="synComment"># int じゃなかったらとりあえず 1 ページ目に返す</span> contacts = paginator.page(<span class="synConstant">1</span>) <span class="synStatement">except</span> EmptyPage: <span class="synComment"># 範囲外ならこの場合最後に飛ばす</span> contacts = paginator.page(paginator.num_pages) <span class="synComment"># 辞書で渡してやる</span> <span class="synStatement">return</span> render_to_response(<span class="synConstant">'list.html'</span>, {<span class="synConstant">&quot;contacts&quot;</span>: contacts}) </pre><p>素の render_to_response だと RequestContext をつつんでくれないかもだからそこらへんは自分でよしなにする。今回は Class Base View で DetailView とかの中で get_context_data で context に上書きするような形にしていたので特に意識しなかった。</p><p>で、テンプレート</p> <pre class="code lang-htmldjango" data-lang="htmldjango" data-unlink> <span class="synComment">&lt;!-- 普通に for で回して表示させる --&gt;</span> <span class="synPreProc">{% </span><span class="synStatement">for</span><span class="synPreProc"> contact </span><span class="synStatement">in</span><span class="synPreProc"> contacts %}</span> <span class="synComment">{# Each &quot;contact&quot; is a Contact model object. #}</span> <span class="synPreProc">{{ contact.full_name|</span><span class="synIdentifier">upper</span><span class="synPreProc"> }}</span><span class="synIdentifier">&lt;</span><span class="synStatement">br</span><span class="synIdentifier"> /&gt;</span> ... <span class="synPreProc">{% </span><span class="synStatement">endfor</span><span class="synPreProc"> %}</span> <span class="synComment">&lt;!-- ページングの処理 --&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">div</span><span class="synIdentifier"> </span><span class="synType">class</span><span class="synIdentifier">=</span><span class="synConstant">&quot;pagination&quot;</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">span</span><span class="synIdentifier"> </span><span class="synType">class</span><span class="synIdentifier">=</span><span class="synConstant">&quot;step-links&quot;</span><span class="synIdentifier">&gt;</span> <span class="synPreProc">{% </span><span class="synStatement">if</span><span class="synPreProc"> contacts.has_previous %}</span> <span class="synComment">&lt;!-- ここでクエリストリングにページをわたしてやる。 --&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">a</span><span class="synIdentifier"> </span><span class="synType">href</span><span class="synIdentifier">=</span><span class="synConstant">&quot;?page=</span><span class="synPreProc">{{ contacts.previous_page_number }}</span><span class="synConstant">&quot;</span><span class="synIdentifier">&gt;</span><span class="synUnderlined">previous</span><span class="synIdentifier">&lt;/</span><span class="synStatement">a</span><span class="synIdentifier">&gt;</span> <span class="synPreProc">{% </span><span class="synStatement">endif</span><span class="synPreProc"> %}</span> <span class="synIdentifier">&lt;</span><span class="synStatement">span</span><span class="synIdentifier"> </span><span class="synType">class</span><span class="synIdentifier">=</span><span class="synConstant">&quot;current&quot;</span><span class="synIdentifier">&gt;</span> Page <span class="synPreProc">{{ contacts.number }}</span> of <span class="synPreProc">{{ contacts.paginator.num_pages }}</span>. <span class="synIdentifier">&lt;/</span><span class="synStatement">span</span><span class="synIdentifier">&gt;</span> <span class="synPreProc">{% </span><span class="synStatement">if</span><span class="synPreProc"> contacts.has_next %}</span> <span class="synIdentifier">&lt;</span><span class="synStatement">a</span><span class="synIdentifier"> </span><span class="synType">href</span><span class="synIdentifier">=</span><span class="synConstant">&quot;?page=</span><span class="synPreProc">{{ contacts.next_page_number }}</span><span class="synConstant">&quot;</span><span class="synIdentifier">&gt;</span><span class="synUnderlined">next</span><span class="synIdentifier">&lt;/</span><span class="synStatement">a</span><span class="synIdentifier">&gt;</span> <span class="synPreProc">{% </span><span class="synStatement">endif</span><span class="synPreProc"> %}</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">span</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">div</span><span class="synIdentifier">&gt;</span> </pre><p>難しいことはやってないんだけどもう一度いうと</p> <ul> <li>paginator オブジェクトがページング全体の情報を持っている</li> <li>pages = paginator.page(page) みたいにして pages オブジェクトにオブジェクトの配列にして返してやってつかったりする</li> <li>そのために ?page= というように request.GET の辞書につめこんでいる</li> </ul><p>という流れになっている。なので、 urls.py とかでうけとってよしなにしようとか paginator オブジェクトの中とは別で pages でオブジェクトを生成する必要があるっていうあたりがハマりどろだった。</p> </div> <div class="section"> <h3>まあ</h3> <p>思えばはじめて Django というか Web アプリケーション<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EC%A1%BC%A5%E0%A5%EF%A1%BC%A5%AF">フレームワーク</a>さわったちょうど2年前くらいはページングの実装とか自分でがんばってたなーとかうまくいかないなーとか<a href="#f1" name="fn1" title="それで django-pagination をつかった">*1</a>、思い出した。素直にドキュメント読んで使えるレベルになっただけ、2年前とは変わったのかなぁ、なんて。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">それで django-pagination をつかった</span></p> </div> atasatamatara vim で python 開発するとき pyflakes + PEP8 = flake8 が便利 hatenablog://entry/6435988827676726556 2013-04-02T20:14:29+09:00 2013-04-02T20:14:29+09:00 補完とかは Python 開発で便利な jedi-vim いれてみたらたしかにライフチェンジングだった - AtAsAtAmAtArA とかみよう。 PEP8 する必要があった 今まではシンタックスだけの pyflakes だけしてた。PEP8 はある程度守ってるけど80行折り返しと行間については多少自分のやり方でまあいいかなって思ってからだ。でも今回は PEP8 準拠でやろうってことになった。ということで vim-pep8 いれようとしたらなくなってて、 flake8 ってのに統一されてた。 flake8 ってなに pyflakes + PEP8 つまりシンタックスチェックと python … <p>補完とかは <a href="http://atasatamatara.hatenablog.jp/entry/2013/03/05/221745">Python &#x958B;&#x767A;&#x3067;&#x4FBF;&#x5229;&#x306A; jedi-vim &#x3044;&#x308C;&#x3066;&#x307F;&#x305F;&#x3089;&#x305F;&#x3057;&#x304B;&#x306B;&#x30E9;&#x30A4;&#x30D5;&#x30C1;&#x30A7;&#x30F3;&#x30B8;&#x30F3;&#x30B0;&#x3060;&#x3063;&#x305F; - AtAsAtAmAtArA</a> とかみよう。</p> <div class="section"> <h3>PEP8 する必要があった</h3> <p>今まではシンタックスだけの pyflakes だけしてた。PEP8 はある程度守ってるけど80行折り返しと行間については多少自分のやり方でまあいいかなって思ってからだ。でも今回は PEP8 準拠でやろうってことになった。ということで <a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-pep8 いれようとしたらなくなってて、 flake8 ってのに統一されてた。</p> </div> <div class="section"> <h3>flake8 ってなに</h3> <p>pyflakes + PEP8 つまりシンタックスチェックと <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> 的なコーディングルールの両方をパッケージにしたもの。<br /> <a href="https://pypi.python.org/pypi/flake8/">flake8 2.0 : Python Package Index</a></p> </div> <div class="section"> <h3>flake8 導入</h3> <p>まんまです</p> <pre class="code lang-sh" data-lang="sh" data-unlink>pip <span class="synStatement">install</span> flake8 </pre><p>virtualenv 環境だし virtualenv.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> もいれてます。</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> でつかう</h3> <p><a href="https://github.com/nvie/vim-flake8/blob/master/ftplugin/python_flake8.vim">vim-flake8/ftplugin/python_flake8.vim at master &middot; nvie/vim-flake8 &middot; GitHub</a><br /> <a href="http://www.cs.dartmouth.edu/~nfoti/blog/blog/2012/07/22/using-syntastic-with-vim/">Using syntastic with vim (and a vim bug on OSX) - Statisfactory</a><br /> 自分の場合 syntactic + pyflakes でやってるのでいろいろ試行錯誤した結果 pyflakes-pathogen + <a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-flake8 に落ち着いた。なんか公式だと「<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-pathogen でやってね」ってあるけど、自分は NeoBundle だし、じゃあ <a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-pathogen いれて pyflakes-pathogen やめたりしたら syntactic でシンタックスが自動化されなくて微妙だったからこうした。</p> </div> <div class="section"> <h3>まあ</h3> <p>flake8 めっちゃべんり</p> <div class="section"> <h4>あと、PEP8って</h4> <p>けっこうメジャーなライブラリでも完全には順守されてないっぽい感じではあった。Django とか(Django は Pyhton じゃないよねとかそういうあれではなくて)。こうして自動チェックいれてしまうとそれ準拠じゃないとかえって気持ち悪いくらいになっちゃうけど、じゃあそれを言語仕様までにいれたらキツすぎるのはまあある。パーフェクト<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> の感想で「Zen of <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> いいね」みたいなことかいたけど、「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> のインデントだるい」という感覚少し思い出した。感じた。</p> </div> </div> atasatamatara sed + awk をすこしさわった hatenablog://entry/6435988827676696184 2013-04-01T22:08:43+09:00 2013-04-01T22:08:43+09:00 dotinstall で sed と awk の講座が出たから*1せっかくなのでやってみた。思えば grep | sed しか知らないくらいだし、awk なにそれこわいという状態だし。 sed入門 (全10回) - プログラミングならドットインストール AWK入門 (全13回) - プログラミングならドットインストール sed(gsed) GNU sed を使うため、Mac の場合は gnu-sed をインストールする必要がある。 引数 f file e exec これは省略可能 i repalce n あんまりわかってないけど sed -n 'p' file みたいに p するときに他のを出… <p>dotinstall で <a class="keyword" href="http://d.hatena.ne.jp/keyword/sed">sed</a> と <a class="keyword" href="http://d.hatena.ne.jp/keyword/awk">awk</a> の講座が出たから<a href="#f1" name="fn1" title="ちょうどこの記事をかいたとき">*1</a>せっかくなのでやってみた。思えば <a class="keyword" href="http://d.hatena.ne.jp/keyword/grep">grep</a> | <a class="keyword" href="http://d.hatena.ne.jp/keyword/sed">sed</a> しか知らないくらいだし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/awk">awk</a> なにそれこわいという状態だし。<br /> <a href="http://dotinstall.com/lessons/basic_sed">sed&#x5165;&#x9580; (&#x5168;10&#x56DE;) - &#x30D7;&#x30ED;&#x30B0;&#x30E9;&#x30DF;&#x30F3;&#x30B0;&#x306A;&#x3089;&#x30C9;&#x30C3;&#x30C8;&#x30A4;&#x30F3;&#x30B9;&#x30C8;&#x30FC;&#x30EB;</a><br /> <a href="http://dotinstall.com/lessons/basic_awk">AWK&#x5165;&#x9580; (&#x5168;13&#x56DE;) - &#x30D7;&#x30ED;&#x30B0;&#x30E9;&#x30DF;&#x30F3;&#x30B0;&#x306A;&#x3089;&#x30C9;&#x30C3;&#x30C8;&#x30A4;&#x30F3;&#x30B9;&#x30C8;&#x30FC;&#x30EB;</a></p> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/sed">sed</a>(gsed)</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/GNU">GNU</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/sed">sed</a> を使うため、Mac の場合は <a class="keyword" href="http://d.hatena.ne.jp/keyword/gnu">gnu</a>-<a class="keyword" href="http://d.hatena.ne.jp/keyword/sed">sed</a> をインストールする必要がある。</p> <div class="section"> <h4>引数</h4> <ul> <li>f file</li> <li>e exec <ul> <li>これは省略可能</li> </ul></li> <li>i repalce</li> <li>n <ul> <li>あんまりわかってないけど <a class="keyword" href="http://d.hatena.ne.jp/keyword/sed">sed</a> -n 'p' file みたいに p するときに他のを出力しない的な</li> </ul></li> </ul> </div> <div class="section"> <h4>パターンスペース</h4> <p>アドレスに対してコマンドを実行する。記号はだいたい vi 準拠っぽい感じ</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># not</span> <span class="synConstant">3</span>!d <span class="synComment"># それぞれ指定</span> 1d;4d <span class="synComment"># 範囲</span> <span class="synConstant">1</span>,3d <span class="synComment"># 末尾</span> <span class="synPreProc">$d</span> <span class="synComment"># 正規表現っぽいけどちょっと正規表現じゃない操作</span> /hoge$/d </pre> <ul> <li>p = 表示</li> <li>a = apppend</li> <li>i = insert</li> <li>y = copy</li> </ul><p>まあ vi 準拠なので馴染みやすい</p> </div> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a></h4> <p>s/hoge/moge/gi みたいに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>が使える。</p> <ul> <li>Regexp でとったら & で参照</li> <li>(match) (match) で \1 \2 で参照</li> </ul> </div> <div class="section"> <h4>ホールドスペース</h4> <p>パターンスペースの裏でよしなにする。正直難しかったし使わなさそうでだるかった。</p> <ul> <li>パターンスペースのバックグランドで動作する</li> <li>hでhold</li> <li>gでget</li> <li>x で excahge(交換)</li> </ul> </div> <div class="section"> <h4>まあ</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>でしかつかわないかとおもったら d,p,a,i と vi like にできるおどろき。まあでもホールドスペースはつらい。ただ <a class="keyword" href="http://d.hatena.ne.jp/keyword/sed">sed</a> -i.bak でバックアップはいいね。</p> </div> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/awk">awk</a>(<a class="keyword" href="http://d.hatena.ne.jp/keyword/gawk">gawk</a>)</h3> <p>これも Mac だと <a class="keyword" href="http://d.hatena.ne.jp/keyword/gnu">gnu</a>-<a class="keyword" href="http://d.hatena.ne.jp/keyword/awk">awk</a> をいれる必要がある。</p> <div class="section"> <h4>引数と実行</h4> <ul> <li>f file</li> <li>コマンドラインでは '{}' で実行(""はだめ)。文字列<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%C6%A5%E9%A5%EB">リテラル</a>は "hoge" で文字列連結は space で</li> </ul> </div> <div class="section"> <h4>概要</h4> <p>行指向スクリプト。レコードに対してフィールドを操作する。行志向スクリプト, Cっぽいらしい。</p> </div> <div class="section"> <h4>特殊引数</h4> <ul> <li>$0,1,2で参照 $0 は全体</li> <li>NR は行番号</li> <li>NF はフィールドの数</li> </ul> </div> <div class="section"> <h4>文法</h4> <p>大きく分けて処理としては3つになる</p> <ul> <li>BEGIN {...}</li> <li>something(条件など) {...}</li> <li>something(条件など) {...}</li> <li>something(条件など) {...}</li> <li>END {...}</li> </ul><p>BEGIN でよしなに初期設定とかできる。デリミタ(FS(Field Separator))とか、RS でフィールドの区切りとかなんとか。<br /> あと比較<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>と論理<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>とかもある。 (pattern) || (pattern) {command} 比較<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>には<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>もある(~)。if 的条件もある NR < 5 とか。</p> </div> <div class="section"> <h4>関数</h4> <p>文字列、数値、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%B9%A5%C6%A5%E0%A5%B3%A1%BC%A5%EB">システムコール</a>、配列、辞書とかそれっぽいものがひととおりある。</p> <ul> <li>printf あるよ、printf("name:%10s %-5d", $1, $3)</li> <li>変数と代入<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>もあるよ, 文字列は space で連結だよ</li> <li>組み込み関数いろいろあるから使えるよ。 <ul> <li>number は int, log, sin, cos, sqrtとか</li> <li>Stirng は sbustring, length, index, match, splitとか</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%B9%A5%C6%A5%E0%A5%B3%A1%BC%A5%EB">システムコール</a>とかある, timeとか</li> <li>bit演算とか</li> <li>if, for(for in), while ある</li> <li>配列は 1 から</li> <li>辞書もあるよ</li> <li>function name(arg){} で定義できるよ</li> </ul></li> </ul> </div> </div> <div class="section"> <h3>まあ</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%A7%A5%EB%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">シェルスクリプト</a>だるいですね。そりゃ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%A7%A5%EB%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">シェルスクリプト</a>だるくて <a class="keyword" href="http://d.hatena.ne.jp/keyword/Perl">Perl</a> つくったのうれしいね。がんばってパースするのやだ。でも <a class="keyword" href="http://d.hatena.ne.jp/keyword/zsh">zsh</a> とかで使えるかも、しれない。たぶんつらぽよくてきっとやらない。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">ちょうどこの記事をかいたとき</span></p> </div> atasatamatara django-debug-toolbar は便利(とVirtualboxのVMで表示にハマった件について) hatenablog://entry/13425511277527238899 2013-03-26T20:27:08+09:00 2013-08-23T22:12:37+09:00 class base view がわからない 存在は前から知っていたけど、まあ別にいいやって思ってて使ってなかった。でも久々の Django でいろいろ忘れてるし、あと 1.5 を使うのはいいけど class base view が mixin しまくってて拡張や仕様変更や保守に強そうというのはいいんだが単に便利セットが増えたという話だった、やっぱり正直どうつかえばどう動くのかよくわからない。資料はあるが実感がわかない。そういうことでとりあえず発行されている SQL がみたかった。前も ForeignKeyとfilterのメモ - atas でみてたことはあったけどやっぱりだるいのでいい感じの… <div class="section"> <h3>class base view がわからない</h3> <p>存在は前から知っていたけど、まあ別にいいやって思ってて使ってなかった。でも久々の Django でいろいろ忘れてるし、あと 1.5 を使うのはいいけど class base view が mixin しまくってて<s>拡張や仕様変更や保守に強そうというのはいいんだが</s>単に便利セットが増えたという話だった、やっぱり正直どうつかえばどう動くのかよくわからない。資料はあるが実感がわかない。</p><p>そういうことでとりあえず発行されている <a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a> がみたかった。前も <a href="http://atasatamatara.hatenablog.jp/entry/20120730/1343650783">ForeignKey&#x3068;filter&#x306E;&#x30E1;&#x30E2; - atas</a> でみてたことはあったけどやっぱりだるいのでいい感じのデバッガをいれた。</p> </div> <div class="section"> <h3>前提</h3> <p><a href="http://d.hatena.ne.jp/yuheiomori0718/20120910/1347284324">django-generate-scaffold&#x3092;&#x3055;&#x308F;&#x3063;&#x3066;&#x307F;&#x305F;&#x30E1;&#x30E2; - brainstorm</a><br /> <a href="https://github.com/modocache/django-generate-scaffold">modocache/django-generate-scaffold &middot; GitHub</a><br /> を参考に導入した。ただテンプレートタグが url の部分辺りで 1.4 と 1.5 で互換性がないので 1.5 対応修正をしてくれたバージョンを使用した<br /> <a href="https://github.com/drillbits/django-generate-scaffold/tree/django-1.5-support">drillbits/django-generate-scaffold &middot; GitHub</a></p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># github からのインストール</span> <span class="synComment"># egg の部分は任意の名前でいいっぽいけど、いまはよくわかっていない</span> pip <span class="synStatement">install</span> <span class="synSpecial">-e</span> git+https://github.com/drillbits/django-generate-scaffold.git#<span class="synIdentifier">egg</span>=moge <span class="synComment"># 導入した virtualenv 内で git のブランチを切り替える</span> git checkout django<span class="synConstant">-1</span>.<span class="synConstant">5</span>-support </pre> </div> <div class="section"> <h3>導入</h3> <p><a href="http://d.hatena.ne.jp/nullpobug/20090920/1253376112">django-debug-toolbar&#x4FBF;&#x5229; - &#x504F;&#x3063;&#x305F;&#x8A00;&#x8A9E;&#x4FE1;&#x8005;&#x306E;&#x5782;&#x308C;&#x6D41;&#x3057;</a></p> <pre class="code lang-sh" data-lang="sh" data-unlink>pip <span class="synStatement">install</span> django-debug-toolbar </pre><p><a href="https://pypi.python.org/pypi/django-debug-toolbar">django-debug-toolbar 0.9.4 : Python Package Index</a> の公式を参考にして、settings.py に以下の項目を追記する。簡単だけどコピペできるくらいのレベルまで落としておく。</p> <pre class="code lang-python" data-lang="python" data-unlink>INSTALLED_APPS += ( <span class="synComment"># これを追加</span> <span class="synConstant">'debug_toolbar'</span>, ) <span class="synComment"># 許可IP</span> <span class="synComment"># 開発なのでローカル</span> INTERNAL_IPS = (<span class="synConstant">'127.0.0.1'</span>,) MIDDLEWARE_CLASSES += ( <span class="synComment"># これを追加</span> <span class="synConstant">'debug_toolbar.middleware.DebugToolbarMiddleware'</span>, ) </pre><p>とりあえずこれで動く。<a class="keyword" href="http://d.hatena.ne.jp/keyword/PyPi">PyPi</a> にあるドキュメントだとオプションがあるけど、とりあえずデフォルトだと全部有効っぽいのでそのままにしてる。</p> <div class="section"> <h4>追記 ローカルの <a class="keyword" href="http://d.hatena.ne.jp/keyword/Virtualbox">Virtualbox</a> の VM でも表示させる</h4> <p>クライアントは Mac で、開発は <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a> Server でやっている。で、そのときパネルが表示されなかった。ローカルで試すと大丈夫ということは、 INTERNAL_IPS の許可 IP あたりの設定という目星はついた。が、クライアントの IP である 192.168.xxx.xxx を許可してもうまく表示できなかった。</p><p>探した結果、やはり StakOverFlow にいきついた<br /> <a href="http://stackoverflow.com/questions/10517765/django-debug-toolbar-not-showing-up">python - django-debug-toolbar not showing up - Stack Overflow</a><br /> ここでも「Debug=True で許可 IP はサーバーじゃなくてクライアントだよ」とあるけど、それでもだめだったとき「request.META["REMOTE_ADDR"]みろ」ってのが助かった。</p><p>class base view なのでてきとうに TemplateView とかだと request オブジェクトを拾ってくれないので、てきとうに get メソッドの中でブレークさせた</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synStatement">class</span> <span class="synIdentifier">MyView</span>(TemplateView): <span class="synStatement">def</span> <span class="synIdentifier">get</span>(self, request): <span class="synComment"># debug というサードのモジュールつかってるけど、もちろん pdbでもいい</span> <span class="synPreProc">import</span> debug <span class="synComment"># print(request.META[&quot;REMOTE_ADDR&quot;])</span> </pre><p>これの結果が普段ローカルから接続している 192.168.56.101 ではなく 192.168.56.1 となぜか変わっていた。なので、後者を指定することで対応できた。</p> </div> </div> <div class="section"> <h3>結果</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/CRUD">CRUD</a> するボタンをおすと HttpResponseRedirect して、そのなかで update/delete/craete とかルーティングして <a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a> としてはそれぞれ発行してるという挙動がわかりやすかった。</p> </div> <div class="section"> <h3>まあ</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EB%A5%B9%A5%BF">フルスタ</a>ックで利用者が多いとこういう手軽な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D0%A5%C3%A5%B0">デバッグ</a>ツールとか作ってくれてる人がいて助かる(あるいはこういうツールがないとどんどんブラックボックスになっていくというのもまああれなんだけど)。あといまは大丈夫だけど、どう MIDDLEWARE とか TEMPLATE_CONTEXT_PROSECCOR を通過しているかとか Django が内部的にどう動いているのかがわかりやすいからなんかあったときにトラブルシューティングに役立つ。テンプレートの継承やそこで発行されているクエリもみれる。</p> </div> atasatamatara grunt を軽く触ってついでに livereload させてみた hatenablog://entry/6435922169449619424 2013-03-25T20:56:36+09:00 2013-10-16T19:29:37+09:00 Sphinx のビルドをファイル監視して自動で行う - AtAsAtAmAtArA でファイル監視してビルドとかやってるように、ウェブ開発でファイル監視してリロードしたいとかはある。古くは mala さんが location.href に xhr をとばすっていう方法でやってたようだし、それを拡張してるやり方もある。あるいはファイル監視はrubyやpythonにやらせて、ブラウザのリロードは AppleScript やそういうシェルスクリプトにやらせたりする方法もある。で、個人的には JS 関係のことだから Node にやらせたいし、あんまり AppleScript みたいにプラットフォーム依… <p><a href="http://atasatamatara.hatenablog.jp/entry/2013/03/15/200115">Sphinx &#x306E;&#x30D3;&#x30EB;&#x30C9;&#x3092;&#x30D5;&#x30A1;&#x30A4;&#x30EB;&#x76E3;&#x8996;&#x3057;&#x3066;&#x81EA;&#x52D5;&#x3067;&#x884C;&#x3046; - &#x61A7;&#x308C;&#x99C6;&#x52D5;&#x958B;&#x767A;</a> でファイル監視してビルドとかやってるように、ウェブ開発でファイル監視してリロードしたいとかはある。古くは location.href に xhr をとばすっていう方法でやってたようだし、それを拡張してるやり方もある。あるいはファイル監視は<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a>にやらせて、ブラウザのリロードは <a class="keyword" href="http://d.hatena.ne.jp/keyword/AppleScript">AppleScript</a> やそういう<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%A7%A5%EB%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">シェルスクリプト</a>にやらせたりする方法もある。</p><p>で、個人的には JS 関係のことだから Node にやらせたいし、あんまり <a class="keyword" href="http://d.hatena.ne.jp/keyword/AppleScript">AppleScript</a> みたいにプラットフォーム依存なやりかたは嫌だなぁと<a href="#f1" name="fn1" title="とはいえ livereload が対応している拡張は Chrome, Safari, Firefox なのでそれもまたあれなんだけど">*1</a>。xhr で監視も悪くないけど、まあ、grunt ついでにやってみっかってことでやってみた。</p> <div class="section"> <h3>しかしぶっちゃけ</h3> <p>いろいろやってたけど、その xhr をみる方法でよしなにしてくれる <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a> 拡張の livepage ってのがあるから、それを使うほうがなにかと楽な気はする。</p> </div> <div class="section"> <h3>grunt とは</h3> <p>今や説明不要になりつつあるけど、ざっくりいうと Node 製の便利ユーティリティースクリプトみたいなもの。JS や <a class="keyword" href="http://d.hatena.ne.jp/keyword/CSS">CSS</a> を minify したり、coffee や sass をコンパイルしたり、ファイル監視したり、圧縮したり。とかもろもろできる。</p> </div> <div class="section"> <h3>導入と簡単な設定</h3> <p>grunt は最近リリースされたらしい 0.4 系からはちょっとかきかたが変わったらしいので、情報は最新をあたったほうがいいかもしれない。基本的には「grunt.js から Gruntfile.js にかわった」「grunt はグローバルにはおかないで、かわりにgrunt-cli をグローバルにおく」ってあたりらしい。</p><p>導入した package.json をみたほうが早いのではる。npm install grunt-cli -g は別として、これらはそのまま npm install できる</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">{</span> <span class="synConstant">&quot;name&quot;</span>: <span class="synConstant">&quot;my-project-name&quot;</span>, <span class="synConstant">&quot;version&quot;</span>: <span class="synConstant">&quot;0.1.0&quot;</span>, <span class="synConstant">&quot;devDependencies&quot;</span>: <span class="synIdentifier">{</span> <span class="synConstant">&quot;grunt&quot;</span>: <span class="synConstant">&quot;&gt;=0.4.x&quot;</span>, <span class="synConstant">&quot;grunt-contrib-coffee&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-compass&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-compress&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-sass&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-uglify&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-watch&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-concat&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-livereload&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-connect&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-regarde&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-jasmine-node&quot;</span>: <span class="synConstant">&quot;*&quot;</span>, <span class="synConstant">&quot;grunt-contrib-jshint&quot;</span>: <span class="synConstant">&quot;*&quot;</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> </pre><p>とりあえず grunt だけ0.4 系以上にしておいて、あとは全部最新版しておいた。</p><p>npm install するときは引数に --save-dev をつけようと各種 grunt-contrib-* のREADME にはかいてある。あくまで開発中であることを明示したほうがいいとかなんとからしい。<br /> <a href="https://github.com/gruntjs/grunt/wiki/Getting-started">https://github.com/gruntjs/grunt/wiki/Getting-started</a><a href="https://npmjs.org/doc/json.html#devDependencies">package.json</a><a href="http://nantokaworks.com/?p=827">grunt-cli (grunt.js v0.4.x)&#x3067; LiveReload &#x3092;&#x8A66;&#x3057;&#x3066;&#x307F;&#x305F; | Re* Programming</a></p><p>で、Gruntfile.js は livereload 以外のことをやらせた。まあ、たいしたことはしていない。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink> module.exports = <span class="synIdentifier">function</span>(grunt) <span class="synIdentifier">{</span> <span class="synComment">// Project configuration.</span> grunt.initConfig(<span class="synIdentifier">{</span> pkg: <span class="synConstant">'&lt;json:package.json&gt;'</span>, <span class="synComment">// ファイル結合</span> concat: <span class="synIdentifier">{</span> dist: <span class="synIdentifier">{</span> src: <span class="synIdentifier">[</span><span class="synConstant">'../jasmine/src/*'</span><span class="synIdentifier">]</span>, dest: <span class="synConstant">'main.js'</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>, <span class="synComment">// minify と難読化</span> uglify: <span class="synIdentifier">{</span> options: <span class="synIdentifier">{</span> <span class="synComment">// true にすると難読化がかかる。false だと関数や変数の名前はそのまま</span> mangle: <span class="synConstant">true</span> <span class="synIdentifier">}</span>, my_target: <span class="synIdentifier">{</span> files: <span class="synIdentifier">{</span> <span class="synConstant">'main.min.js'</span>: <span class="synIdentifier">[</span><span class="synConstant">'main.js'</span><span class="synIdentifier">]</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>, <span class="synComment">// 圧縮</span> <span class="synComment">// zip 意外にも tar.gz や gzip とかできる</span> compress: <span class="synIdentifier">{</span> options: <span class="synIdentifier">{</span> archive: <span class="synConstant">'archive.zip'</span> <span class="synIdentifier">}</span>, files: <span class="synIdentifier">{</span> src: <span class="synIdentifier">[</span><span class="synConstant">'main.min.js'</span><span class="synIdentifier">]</span>, dest: <span class="synConstant">'destzip'</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>, <span class="synComment">// 文法チェック</span> <span class="synComment">// jslint はきついので個人的にいつも jshint をつかっている</span> jshint: <span class="synIdentifier">{</span> options:<span class="synIdentifier">{</span> jshintrc: <span class="synConstant">'../../.jshintrc'</span> <span class="synComment">// valid JSON file or dict</span> <span class="synIdentifier">}</span>, files: <span class="synIdentifier">[</span><span class="synConstant">'../jasmine/src/*'</span><span class="synIdentifier">]</span> <span class="synIdentifier">}</span>, <span class="synComment">// ファイル監視</span> watch: <span class="synIdentifier">{</span> scripts: <span class="synIdentifier">{</span> files: <span class="synIdentifier">[</span><span class="synConstant">'../jasmine/src/*'</span><span class="synIdentifier">]</span>, <span class="synComment">// 実行タスク</span> tasks: <span class="synIdentifier">[</span><span class="synConstant">'jshint'</span><span class="synIdentifier">]</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>, <span class="synComment">// load task</span> <span class="synComment">// モジュールを読み込んでやる</span> grunt.loadNpmTasks(<span class="synConstant">'grunt-contrib-concat'</span>); grunt.loadNpmTasks(<span class="synConstant">'grunt-contrib-uglify'</span>); grunt.loadNpmTasks(<span class="synConstant">'grunt-contrib-compress'</span>); grunt.loadNpmTasks(<span class="synConstant">'grunt-contrib-jshint'</span>); grunt.loadNpmTasks(<span class="synConstant">'grunt-contrib-watch'</span>); <span class="synComment">// Default task</span> <span class="synComment">// grunt で直接実行すると行われるタスク</span> grunt.registerTask(<span class="synConstant">'default'</span>, <span class="synIdentifier">[</span><span class="synConstant">'concat'</span>, <span class="synConstant">'uglify'</span>, <span class="synConstant">'compress'</span><span class="synIdentifier">]</span>); <span class="synComment">// grunt auto_jshint など引数を与えると実行されるタスク</span> grunt.registerTask(<span class="synConstant">'auto_jshint'</span>, <span class="synIdentifier">[</span><span class="synConstant">'watch'</span><span class="synIdentifier">]</span>); <span class="synIdentifier">}</span>; </pre><p>この場合デフォルトだと「JS ファイルを全部1つにまとめて、minify と難読化して、zip にする」というタスクになる。grunt auto_jshint とすると「監視対象のファイルに変更があったら jshint かけて文法チェック」ということができる。ありがちなケースとしては develeropment では coffee, sass, compass のコンパイルだけして、production では JS(coffee), <a class="keyword" href="http://d.hatena.ne.jp/keyword/CSS">CSS</a>(SCSS) を concat, minify するってのが考えられる。まああとは zip にしてコピーとか。grunt-contrib-* 意外にもプラグインが豊富なのでいろいろできる感じ。</p><p>あと path で ~ が使えないっぽい感じがする。面倒なので<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%EA%C2%D0%A5%D1%A5%B9">相対パス</a>で読み込んだけど、実際は require('path') とかして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%E4%C2%D0%A5%D1%A5%B9">絶対パス</a>を取得するなにかをしたほうがいいかも。</p><p>ちなみに jasmine-node をつかったから grunt-jasmine-node を watch しようとしてみたけど、requirejs 関係の config.js が読めないっぽい感じでうまく動かせなかった。まあ、jasmine-node 自体に自動監視があるから別にいらない気もするけど。</p> </div> <div class="section"> <h3>livereload する</h3> <p>いままではまえがき。こっからが本番。開発中のファイルを監視して変更があったらブラウザをリロードさせる。ちなみにこの livereload 自体はわりと <a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a> 発祥らしいので、guard あたりでも同じような話はある。ファイル監視したら websocket でどうこうみたいな。最近は Windows でも Mac でも <a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a> のサーバーもあるらしい(有償だったりアルファ版っぽいけど)。</p><p>Gruntfile.js はこんな感じ。まあ、公式のまんまだけど。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">// from grunt-contrib-livereload github README</span> <span class="synIdentifier">var</span> path = require(<span class="synConstant">'path'</span>); <span class="synIdentifier">var</span> lrSnippet = require(<span class="synConstant">'grunt-contrib-livereload/lib/utils'</span>).livereloadSnippet; <span class="synIdentifier">var</span> folderMount = <span class="synIdentifier">function</span> folderMount(connect, point) <span class="synIdentifier">{</span> <span class="synStatement">return</span> connect.<span class="synStatement">static</span>(path.resolve(point)); <span class="synIdentifier">}</span>; module.exports = <span class="synIdentifier">function</span>(grunt) <span class="synIdentifier">{</span> <span class="synComment">// Project configuration.</span> grunt.initConfig(<span class="synIdentifier">{</span> pkg: <span class="synConstant">'&lt;json:package.json&gt;'</span>, connect: <span class="synIdentifier">{</span> livereload: <span class="synIdentifier">{</span> options: <span class="synIdentifier">{</span> <span class="synComment">// これは connect のポート</span> <span class="synComment">// livereload のポートはデフォルトだと 35729</span> port: 9001, middleware: <span class="synIdentifier">function</span>(connect, options) <span class="synIdentifier">{</span> <span class="synStatement">return</span> <span class="synIdentifier">[</span>lrSnippet, folderMount(connect, <span class="synConstant">'.'</span>)<span class="synIdentifier">]</span>; <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>, <span class="synComment">// Configuration to be run (and then tested)</span> regarde: <span class="synIdentifier">{</span> <span class="synComment">// fred って名前がなんだかわからないけど、とりあえずそのままにしておいた</span> fred: <span class="synIdentifier">{</span> <span class="synComment">// 監視対象</span> files: <span class="synConstant">'../Public/a.html'</span>, tasks: <span class="synIdentifier">[</span><span class="synConstant">'livereload'</span><span class="synIdentifier">]</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>); <span class="synComment">// load task</span> grunt.loadNpmTasks(<span class="synConstant">'grunt-regarde'</span>); grunt.loadNpmTasks(<span class="synConstant">'grunt-contrib-connect'</span>); grunt.loadNpmTasks(<span class="synConstant">'grunt-contrib-livereload'</span>); <span class="synComment">// Default task</span> grunt.registerTask(<span class="synConstant">'default'</span>, <span class="synIdentifier">[</span><span class="synConstant">'livereload-start'</span>, <span class="synConstant">'connect'</span>, <span class="synConstant">'regarde'</span><span class="synIdentifier">]</span>); <span class="synIdentifier">}</span>; </pre><p>grunt-contrib-livereload を動かすには grunt-contrib-connect という grunt タスク中に立ち上げられるサーバーと(Node の http モジュールとはなんだか別らしい)、grunt-regarde というファイル監視ツールが必要。grunt-contrib-watch ではなく regarde をつかう理由はよくわからないけど、まあそういうものらしい(開発が yeoman だし……)。<br /> <a href="https://github.com/gruntjs/grunt-contrib-livereload">gruntjs/grunt-contrib-livereload &middot; GitHub</a><a href="https://github.com/gruntjs/grunt-contrib-connect">gruntjs/grunt-contrib-connect &middot; GitHub</a><a href="https://github.com/yeoman/grunt-regarde">yeoman/grunt-regarde &middot; GitHub</a></p><p>これで grunt の監視と livereload サーバーが立っている状態になる。ポートはデフォルトだと35729であって、connect でたちあがってるポートではない。で、その上で開発対象のクライアントになんかしらの方法で接続を確立しなければいけない。ので、開発対象のファイルにスニペットをおくか、専用のブラウザ拡張をいれる必要がある。</p> <div class="section"> <h4>スニペットをおく</h4> <p>個人的にはあまりやりたくないけど、README にあるような方法で埋め込めば動く。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink>&lt;!-- livereload snippet --&gt; &lt;script&gt;<span class="synStatement">document</span>.write(<span class="synConstant">'&lt;script src=</span><span class="synSpecial">\&quot;</span><span class="synConstant">http://'</span> + (<span class="synStatement">location</span>.host || <span class="synConstant">'localhost'</span>).split(<span class="synConstant">':'</span>)<span class="synIdentifier">[</span>0<span class="synIdentifier">]</span> + <span class="synConstant">':36729/livereload.js?snipver=1</span><span class="synSpecial">\&quot;</span><span class="synConstant">&gt;&lt;</span><span class="synSpecial">\\</span><span class="synConstant">/script&gt;'</span>) &lt;/script&gt; </pre><p>もちろん全ファイルだとか基底ファイルとか監視用のファイルに埋め込まなきゃいけないから、テンプレートで継承しているならともかく静的にわかれてたら面倒ですね。</p> </div> <div class="section"> <h4>ブラウザ拡張をつかう</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a> には専用の拡張があるのでいれる。注意点としては、おそらくだけど「ファイルのURLアクセスを許可する」みたいなオプションはオンにしておかないと接続が確立できないっぽいので、許可しよう。</p> </div> </div> <div class="section"> <h3>まあ</h3> <p>ライフチェンジングかはわからないけど、watchdog 自動ビルドみたいにやっぱり勝手にやってくれるのは気分がいいですね。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">とはいえ livereload が対応している拡張は <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a> なのでそれもまたあれなんだけど</span></p> </div> atasatamatara JavaScript、奥が深すぎる hatenablog://entry/13425511277527254716 2013-03-23T22:06:58+09:00 2013-08-23T22:14:08+09:00 今まで JS 関連のことをぽつぽつエントリにしていたけど、それにはみ出るトピックを羅列する。 いちばん印象的だったところ 関数について考えること。いまのところ、JavaScript を復習するにあたってこれがいちばんの大本になると思う。プログラミング全般というか、それこそ手続き型に対して関数型とあるけれど、こうしていろいろやってみるとオブジェクトのプロパティに関数をいれておけるということ、それを使い倒せるというのがどれだけ世界を広げることなのかっていうのが、こう、すこし世界が広がった感がある。同時にいろいろついていけない感もある。あとは JavaScript をクライアントサイドで使ってると歴… <p>今まで JS 関連のことをぽつぽつエントリにしていたけど、それにはみ出るトピックを羅列する。</p> <div class="section"> <h3>いちばん印象的だったところ</h3> <p>関数について考えること。いまのところ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> を復習するにあたってこれがいちばんの大本になると思う。プログラミング全般というか、それこそ手続き型に対して関数型とあるけれど、こうしていろいろやってみるとオブジェクトのプロパティに関数をいれておけるということ、それを使い倒せるというのがどれだけ世界を広げることなのかっていうのが、こう、すこし世界が広がった感がある。同時にいろいろついていけない感もある。</p><p>あとは <a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> をクライアントサイドで使ってると歴史的背景としても(そして自分のプログラミングのきっかけが JS というのもあって)DOM 操作をいかにするかってことを考えてしまって整理がつかなくなる。それを「<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> が言語として提供している分野」「DOM を扱うという意味での <a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>」「サーバーサイドの <a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>」というのを意識して分けて考えるきっかけになったと思う。</p><p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774152439/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/516SL6cVQcL._SL160_.jpg" class="hatena-asin-detail-image" alt="JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技" title="JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774152439/hatena-blog-22/">JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> JSサポーターズ</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2012/08/31</li><li><span class="hatena-asin-detail-label">メディア:</span> 単行本(ソフトカバー)</li><li><span class="hatena-asin-detail-label">購入</span>: 38人 <span class="hatena-asin-detail-label">クリック</span>: 1,796回</li><li><a href="http://d.hatena.ne.jp/asin/4774152439/hatena-blog-22" target="_blank">この商品を含むブログ (11件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div><br /> <div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414813X/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/51yrjFsf-2L._SL160_.jpg" class="hatena-asin-detail-image" alt="パーフェクトJavaScript (PERFECT SERIES 4)" title="パーフェクトJavaScript (PERFECT SERIES 4)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414813X/hatena-blog-22/">パーフェクトJavaScript (PERFECT SERIES 4)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> 井上誠一郎,土江拓郎,浜辺将太</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2011/09/23</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><span class="hatena-asin-detail-label">購入</span>: 24人 <span class="hatena-asin-detail-label">クリック</span>: 588回</li><li><a href="http://d.hatena.ne.jp/asin/477414813X/hatena-blog-22" target="_blank">この商品を含むブログ (12件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div><br /> <div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477415489X/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/51Ozp14X8CL._SL160_.jpg" class="hatena-asin-detail-image" alt="JavaScript徹底攻略 (WEB+DB PRESS plus)" title="JavaScript徹底攻略 (WEB+DB PRESS plus)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477415489X/hatena-blog-22/">JavaScript徹底攻略 (WEB+DB PRESS plus)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> 沖林正紀,吾郷協,<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B9%E2%B6%B6%C0%AC%B5%C1">高橋征義</a>,名村卓,桜井雅史,縣俊貴,太田昌吾,天野祐介,飯塚直,佐藤鉄平,冨田慎一,<a class="keyword" href="http://d.hatena.ne.jp/keyword/WEB%2BDB%20PRESS">WEB+DB PRESS</a>編集部</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2013/01/26</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><span class="hatena-asin-detail-label">購入</span>: 7人 <span class="hatena-asin-detail-label">クリック</span>: 69回</li><li><a href="http://d.hatena.ne.jp/asin/477415489X/hatena-blog-22" target="_blank">この商品を含むブログ (6件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p> </div> <div class="section"> <h3>関数が関数を扱うということ</h3> <p>JS に限らない話で <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> でもそうでなくてもなんでもそうだけど、特に JS をいままで扱ってて感じた。関数が関数を引数にとる。関数が関数を返す。関数が関数を合成する。こういったものを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B9%E2%B3%AC%B4%D8%BF%F4">高階関数</a>と呼ぶらしい。f(x,y)を f(x)(y) とさせるのがカリー化とするらしい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> ではよくあるけどデコレータも関数をラップして扱うようなもの。クロージャはとりあえず JS においては状態をもった関数を作成できる。</p><p>関数ってのはいくらかの処理をかためたものでそれを再利用しやすくしたりするっていう意味はもちろんあるんだけど、それだけじゃなくて、関数が柔軟に扱えるということは処理をフックしたりラップしたりメソッドチェインさせたりできる。いまの自分の理解だとあまりこれ以上はおもいつかないけど、だいぶ黒魔術ではないが幅が広がる話で、ものすごく柔軟にさせている。これは直感<a href="#f1" name="fn1" title="そういう意味では Python において lambda が貧弱って話をきくけど、そういうことなのかなぁと感じる">*1</a>。</p><p>ところでクロージャの話はパーフェクト <a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> の解説はすごかった。ちょっと正直よくわからない。いまは表面的につかえればいいやというところ。</p> </div> <div class="section"> <h3>プロトタイプチェーンの終端</h3> <p>前に <a href="http://atasatamatara.hatenablog.jp/entry/2013/02/15/210231">JavaScript &#x306E;&#x540D;&#x524D;&#x7A7A;&#x9593;&#x306B;&#x306A;&#x305C; Function Object &#x3092;&#x3064;&#x304F;&#x308B;&#x3093;&#x3060;&#x308D;&#x3046;&#x3063;&#x3066;&#x8A71; - atas</a> でぷととタイプチェインの話を書いたけど、たぶん、一番誤解していたのは「プロトタイプチェーンの終端は Object」って思ってたところで、そうではなくて、「Object.prototype」だ。だから Object.create(Object.prototype) すると「純粋なオブジェクトが得られる」というのは、Object 自体は Object.prototype をもつから純粋ではない。というのがいまのところの理解。</p> </div> <div class="section"> <h3>メソッドチェインと再帰について</h3> <p>前に <a href="http://atasatamatara.hatenablog.jp/entry/2013/03/19/211228">&#x3044;&#x307E;&#x3055;&#x3089; JSDeferred &#x3068; $.Deferred &#x3092;&#x5C11;&#x3057;&#x3055;&#x308F;&#x3063;&#x305F;&#x30E1;&#x30E2; - atas</a> というのを書いたけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a> でもメソッドチェインで処理をつなげてかけるのがよい。で、具体的には $ にメソッドを生やせば $.func として使え、$.fn = func としてメソッドを生やせば $(selector).func としてつかえる。実装をみてはいないけど、たぶん内部的にはなんらかの状態を変化させた <a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a> Object を返しているんだと思っている。</p><p>再帰という考え方は知っていても使えることはなかった。でもこういう実装が再帰的なのかなと思っている。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%D8%BF%F4%B7%BF%B8%C0%B8%EC">関数型言語</a>をちゃんとやったことはないけど、「for ループの代わりに再帰をつかうと考えるとわかりやすい」と本にあったように、for でループさせないならば、再帰的に参照してぐるぐるまわすしかない。</p><p>そういうところが似ているなぁと感じた。冒頭の「関数が重要」というのは、ここらへんをみてみて感じたところでもある。</p> </div> <div class="section"> <h3>プロパティとアトリビュートについて</h3> <p>JS としてはプロパティを持っていて、DOM としてはアトリビュート(属性)を持っている。クラスベースの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%D6%A5%B8%A5%A7%A5%AF%A5%C8%BB%D8%B8%FE">オブジェクト指向</a>だとフィールドとメソッドをあわせてメンバーと呼ぶっぽいけど、JS だとあくまでプロパティに関数が入っているものが便宜的にメソッドと呼ばれているらしい。</p><p>混同しやすいところは、DOM を触るときもプロパティアクセスっぽい感じで記述できるというところだ。具体的には img.src = path とか location.href とかそういう。それらはプロパティアクセスっぽいし実際そうかけるのは楽で直感的だけど、たぶん、JS と DOM を区別して考えようとするときに混乱する。</p><p>命名とか名前とかなんて便宜的なものでどうでもいいというかもしれない。でも、JS が DOM をさわるクライアントサイドの言語としての意味合いとサーバーサイドで実行されることもある現在、そしてクラスベースではなくてプロトタイプベースであるのもあって、JS が提供している部分と DOM を扱う部分は別に考えたほうが長期的には意味があると思っている。</p> </div> <div class="section"> <h3>同期と非同期って話と、functionかcallbackかは別</h3> <p>処理が同期であるか非同期であるかってのと function なのか callback なのかは別だ。たしかに setTimeout や xhr で飛ばしたあとの関数は callback で非同期だけど、リスナーでイベントを登録された関数は callback だけど同期的に処理されると考えていいとおもう。あんまり厳密に考えなくてもいいのかもしれないけど、なんだろう、意識の違いかな。</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%BE%C1%B0%B6%F5%B4%D6">名前空間</a>と関数オブジェクト</h3> <p><a href="http://atasatamatara.hatenablog.jp/entry/2013/02/15/210231">JavaScript &#x306E;&#x540D;&#x524D;&#x7A7A;&#x9593;&#x306B;&#x306A;&#x305C; Function Object &#x3092;&#x3064;&#x304F;&#x308B;&#x3093;&#x3060;&#x308D;&#x3046;&#x3063;&#x3066;&#x8A71; - atas</a> とかいたけど、実際たしかに Object でもいいパターンはあるようだ。でも、たいがいなにか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%BE%C1%B0%B6%F5%B4%D6">名前空間</a>として渡したいものって関数だし、関数だと call/apply/bind が使えるからそのほうが便利だよねとか。これは直感的に感じた。</p> </div> <div class="section"> <h3>JS でも内部を隠したい話</h3> <p>UserScript とか GreeseMonkey とかならともかく、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%BE%C1%B0%B6%F5%B4%D6">名前空間</a>としてグローバルに1つだけ追加したら別に中身は隠さなくてもいいのでは?と思っていたけど、それでもあくまで private にもっておきたいものは JS でも匿名関数 + クロージャで隠蔽してしまうのが筋のいいやり方なのかなぁと。</p> </div> <div class="section"> <h3>構文について</h3> <p>JS は文と式で成り立っている。式は式と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>で成り立っている。というところまではよかったけど、もっと突き詰めていくと式は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%C6%A5%E9%A5%EB">リテラル</a>と識別子(変数)になる話。たぶん自分は識別子と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>ってあたりまでは区別がついてたけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%C6%A5%E9%A5%EB">リテラル</a>ってのはまた別物として分けられるんだなぁと。</p> </div> <div class="section"> <h3>型変換について</h3> <p>「== の比較は型変換がおこるからバッドなやりかた」とは知ってたから避けるようにはしてたけど、でも if (hoge) したときには型変換がおこっている。静的型付けと動的型付けの話は正直まだそこまでよくわかっていないけど、少なくても JS においても型はあるし、それを動的に変換したり暗黙的に変換することがある。ということは頭の片隅においておこうとおもった。</p> </div> <div class="section"> <h3>map, filter, リスト内包、ジェネレーター</h3> <p>map, filter は ES5, リスト内包, ジェネレーターは ES6 な内容だけど、 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> からはいったからそこらへんはとっつきやすかった。ただ JS 以外の言語を知らない状態でやってたらだいぶいろいろ苦しかった気がする。</p> </div> <div class="section"> <h3>というかジェネレーターオブジェクトの自作すごい</h3> <p>パーフェクト <a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> にあったけど、ジェネレーターオブジェクトを実装してみるってところ、すごい。</p> </div> <div class="section"> <h3>iframe で子要素孫要素でコールバックさせるテク、すごい</h3> <p>わりと古典的というか XHR2 の前はそういうことを駆使していたっぽいんだけど、初めて知った。ざっくりいうと親 window に対してクロスドメイン通信したい対象を iframe でおいておく(子iframe)。で、その子iframe から受け取った値は親 window と同じドメインの孫 iframe に通信させる。で、その孫 iframe から親 window にコールバックさせて値をとる。すごい。</p> </div> <div class="section"> <h3>Node におけるカスタムイベント</h3> <p><a href="http://atasatamatara.hatenablog.jp/entry/2013/03/20/210348">JavaScript &#x95A2;&#x9023;&#x306E;&#x3061;&#x3087;&#x3063;&#x3068;&#x3057;&#x305F;&#x30E1;&#x30E2; - atas</a> でカスタムイベントのことを書いたけど、Node だとそこらへんは emit って形でそもそも提供してるんですね。Socket.io さわったから知ってはたけど、そもそもカスタムイベントはその emit で管理してしまうものなんだなぁと。Node あたりの詳細はあんまり追いかけてないので知らなかった。</p> </div> <div class="section"> <h3>状態(state)で考える <a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a> パターンはいいね</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/GoF">GoF</a> な話らしいけど、具体的に「if でフラグをたくさんもたせたコードがどうみてもスパゲティにしかならないよね」ってときに「それは状態で考えてつくるといいよ」というのはとても実践的だった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%B6%A5%D1%A5%BF">デザパタ</a>な話は昔座学的に読んで概念としては知っててもどう実際現場で使えるのかよくわからないってことが多いので、ひとつの参考になった。</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>の (?:hoge|moge) はマッチしてもつかわないという意味</h3> <p>JS とは関係ないかも。グループしたときに (hoge|moge) ってやるとそれらを RegExp.$1 とかでとれるってのはしってたけど、別にマッチした値をあとで使いたいわけじゃないときはこうして (?:hoge|moge) としたほうが筋がいいとおもう。</p> </div> <div class="section"> <h3>まあ</h3> <p>かなりざっくりとかいたけど、「それはちゃうだろ」ってところがあったらコメントか <a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a> かなんでもいいのでそれとなく伝えてくれるとうれしい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> をナメてたつもりはないけど、だいぶすごい。言語として限定した上でも、プログラミング、奥が深すぎる。正直ついていけない。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">そういう意味では <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> において lambda が貧弱って話をきくけど、そういうことなのかなぁと感じる</span></p> </div> atasatamatara jasmine-node で JavaScript のロジックのテストをする hatenablog://entry/6435922169449667530 2013-03-22T20:16:22+09:00 2013-03-22T20:16:23+09:00 JS でもテストしたい DOM や非同期はおいといて、ロジックくらいテストしたい。Sinon.js とかモックしたり、非同期処理のテストのライブラリがあったり、それこそ古くからは Selenium とかあるけど、いまはそこまでしなくていいから JS でテストをするってのをやりたかった。で、いろいろあるけど Jasmine がとりあえず楽らしいし、コンソールでやりたいので jasmine-node を利用した。 JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技作者: JSサポーターズ出版社/メーカー: 技術評論社発売日: 2012/08/31メディア: 単行本(ソフトカバ… <div class="section"> <h3>JS でもテストしたい</h3> <p>DOM や非同期はおいといて、ロジックくらいテストしたい。Sinon.js とかモックしたり、非同期処理のテストのライブラリがあったり、それこそ古くからは <a class="keyword" href="http://d.hatena.ne.jp/keyword/Selenium">Selenium</a> とかあるけど、いまはそこまでしなくていいから JS でテストをするってのをやりたかった。で、いろいろあるけど Jasmine がとりあえず楽らしいし、コンソールでやりたいので jasmine-node を利用した。<br /> <div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774152439/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/516SL6cVQcL._SL160_.jpg" class="hatena-asin-detail-image" alt="JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技" title="JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774152439/hatena-blog-22/">JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> JSサポーターズ</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2012/08/31</li><li><span class="hatena-asin-detail-label">メディア:</span> 単行本(ソフトカバー)</li><li><span class="hatena-asin-detail-label">購入</span>: 38人 <span class="hatena-asin-detail-label">クリック</span>: 1,794回</li><li><a href="http://d.hatena.ne.jp/asin/4774152439/hatena-blog-22" target="_blank">この商品を含むブログ (11件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p> </div> <div class="section"> <h3>jasmine-node の導入と簡単なテスト</h3> <p>基本的にはこれを参考にした<br /> <a href="http://d.hatena.ne.jp/delaemon/20111115/1321326135">jasmine-node&#x3092;&#x4F7F;&#x3063;&#x3066;&#x30C6;&#x30B9;&#x30C8; - &#x30C7;&#x30E9;&#x30A8;&#x30E2;&#x30F3;&#x3001;&#x30AB;&#x30A4;&#x30CF;&#x30C4;&#x30CB;&#x30C3;&#x30AD;</a><br /> てきとうにディレクトリを掘って作業する。</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># てきとうにつうる</span> <span class="synStatement">mkdir</span> jasmine <span class="synStatement">cd</span> jasmine <span class="synComment"># lib でもいいかも</span> <span class="synStatement">mkdir</span> src <span class="synComment"># テストケース、spec</span> <span class="synStatement">mkdir</span> spec <span class="synComment"># 導入</span> npm <span class="synStatement">install</span> jasmine-node </pre><p>src 以下に元となるコード、spec 以下にテストケースをかく。spec のことはあまりしらないけど、unittest だと class に HogeTest(unittest.TestCase) っていれたり def test_hoge(self) するように、どうやら Spec では MySpec(mixedCase)か my_spec(lower_case) にするらしい。関係なくマッチさせるには --matchall ってオプションをつければ良い。あと --verbose で詳細がでるとかはまあ --help みればよい。</p> <pre class="code lang-sh" data-lang="sh" data-unlink>/path/to/node_modules/jasmine-node/bin/jasmine-node ./spec/ <span class="synSpecial">--autotest</span> <span class="synSpecial">--color</span> </pre><p>よい</p> </div> <div class="section"> <h3>requirejs で依存している他のモジュールも一括でテストしたい</h3> <p>@__10100__ さんの を参考にした <a href="http://d.hatena.ne.jp/naka-06_18/20130123/1358956593">jasmine-node &#x3068;RequireJS - &#x65AD;&#x7AE0;10100</a><br /> この記事だと src 以下に config.js を置いているけど、自分はプロジェクトルートにおいておいた。config.js はこんなかんじでほぼ同じ。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> requirejs = require(<span class="synConstant">&quot;requirejs&quot;</span>); requirejs.config(<span class="synIdentifier">{</span> <span class="synComment">// node のモジュールはそのまま</span> nodeRequire: require, <span class="synComment">// spec 実行時に __dirname が spec のパスにかわるため</span> <span class="synComment">// ちゃんとやるなら require('path') で絶対パス求めたほうがいいかも</span> baseUrl: __dirname + <span class="synConstant">'/../src'</span> <span class="synIdentifier">}</span>); </pre><p>requirejs の config については以下も参考にした。<br /> <a href="http://d.hatena.ne.jp/maneater_rhythm/">&#x304C;&#x3076;&#x3063;&#x3068;&#x3072;&#x3068;&#x304B;&#x307F;</a><br /> shim で記述できないか試したけどちょっとうまくいかなかった。まあ、後述の方法で対処した。</p><p>RequireJS の内容を踏まえて同時にファイル監視もついでにまわしてやることにした</p> <pre class="code lang-sh" data-lang="sh" data-unlink>/path/to/node_modules/jasmine-node/bin/jasmine-node <span class="synSpecial">--runWithRequireJs</span> <span class="synSpecial">--requireJsSetup</span> config.js ./spec/ <span class="synSpecial">--autotest</span> <span class="synSpecial">--color</span> </pre><p>なので、いままでオレオレで習作してたコードを試したりもした。</p><p>src/a.js の文字列のやつなら</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synType">String</span>.prototype.format = <span class="synIdentifier">function</span> (arg) <span class="synIdentifier">{</span> <span class="synComment">// @param {String} or {Object}</span> <span class="synComment">// this = String</span> <span class="synIdentifier">var</span> tmp = <span class="synIdentifier">this</span>; <span class="synComment">// Object</span> <span class="synStatement">if</span> (<span class="synStatement">typeof</span> arg === <span class="synConstant">&quot;object&quot;</span>)<span class="synIdentifier">{</span> <span class="synStatement">for</span> (<span class="synIdentifier">var</span> elem <span class="synStatement">in</span> arg)<span class="synIdentifier">{</span> tmp = tmp.replace(<span class="synConstant">&quot;{&quot;</span> + elem + <span class="synConstant">&quot;}&quot;</span>, arg<span class="synIdentifier">[</span>elem<span class="synIdentifier">]</span>); <span class="synIdentifier">}</span> <span class="synComment">// String</span> <span class="synIdentifier">}</span> <span class="synStatement">else</span> <span class="synIdentifier">{</span> <span class="synStatement">for</span> (<span class="synIdentifier">var</span> i=0; i &lt; <span class="synIdentifier">arguments</span>.length; i++) <span class="synIdentifier">{</span> tmp = tmp.replace(<span class="synConstant">&quot;{&quot;</span> + i + <span class="synConstant">&quot;}&quot;</span>, <span class="synIdentifier">arguments[</span>i<span class="synIdentifier">]</span>); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> <span class="synStatement">return</span> tmp; <span class="synIdentifier">}</span>; </pre><p>spec/a_spec.js でたとえばこんな感じ。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink>requirejs(<span class="synIdentifier">[</span><span class="synConstant">'a'</span><span class="synIdentifier">]</span>, <span class="synIdentifier">function</span> (a) <span class="synIdentifier">{</span> describe(<span class="synConstant">&quot;おれおれフォーマッター&quot;</span>, <span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> str_obj = <span class="synStatement">null</span>; <span class="synIdentifier">var</span> str_ary = <span class="synStatement">null</span>; beforeEach(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> str_obj = <span class="synStatement">new</span> a.<span class="synType">String</span>(<span class="synConstant">&quot;abc {hoge} {moge}&quot;</span>); str_ary = <span class="synStatement">new</span> a.<span class="synType">String</span>(<span class="synConstant">&quot;abc {0} {1}&quot;</span>); <span class="synIdentifier">}</span>); it(<span class="synConstant">&quot;自作 String.format 1&quot;</span>, <span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> describe(<span class="synConstant">&quot;object のとき&quot;</span>, <span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> <span class="synComment">// なにもしない場合</span> expect(str_obj).toEqual(<span class="synConstant">&quot;abc {hoge} {moge}&quot;</span>); <span class="synComment">// 引数を入れる object</span> expect(str_obj.format(<span class="synIdentifier">{</span>hoge: <span class="synConstant">&quot;text&quot;</span><span class="synIdentifier">}</span>)).toEqual(<span class="synConstant">&quot;abc text {moge}&quot;</span>); <span class="synComment">// 引数を複数入れる object</span> expect(str_obj.format(<span class="synIdentifier">{</span>hoge: <span class="synConstant">&quot;text1&quot;</span>, moge: <span class="synConstant">&quot;text2&quot;</span><span class="synIdentifier">}</span>)).toEqual(<span class="synConstant">&quot;abc text1 text2&quot;</span>); <span class="synIdentifier">}</span>); describe(<span class="synConstant">&quot;ary っぽくするとき&quot;</span>, <span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> <span class="synComment">// なにもしない場合</span> expect(str_ary).toEqual(<span class="synConstant">&quot;abc {0} {1}&quot;</span>); <span class="synComment">// 引数を入れる array int</span> expect(str_ary.format(1)).toEqual(<span class="synConstant">&quot;abc 1 {1}&quot;</span>); <span class="synComment">// 引数を入れる array string</span> expect(str_ary.format(<span class="synConstant">&quot;baba&quot;</span>)).toEqual(<span class="synConstant">&quot;abc baba {1}&quot;</span>); <span class="synComment">// 引数を複数入れる array int</span> expect(str_ary.format(4,5)).toEqual(<span class="synConstant">&quot;abc 4 5&quot;</span>); <span class="synComment">// 引数を複数入れる array string</span> expect(str_ary.format(<span class="synConstant">&quot;moha&quot;</span>, <span class="synConstant">&quot;toge&quot;</span>)).toEqual(<span class="synConstant">&quot;abc moha toge&quot;</span>); <span class="synComment">// 引数を複数入れる array string int</span> expect(str_ary.format(<span class="synConstant">&quot;moha&quot;</span>, 4)).toEqual(<span class="synConstant">&quot;abc moha 4&quot;</span>); <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span>); </pre><p>いいですね。あとはゴリゴリかいていくだけです。実際いくつかコケて修正しました。</p> </div> <div class="section"> <h3>ついでに - CommonJS, <a class="keyword" href="http://d.hatena.ne.jp/keyword/AMD">AMD</a> について</h3> <p>RequireJS って単純に依存関係を管理したいだけだと思ってたんだけど、実際はもうちょっとあって、非同期読み込みとモジュール化による<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%BE%C1%B0%B6%F5%B4%D6">名前空間</a>の提供が目的らしい。もうちょっと言えば RequireJS 以前の提案があったらしいが、実装としていまは RequireJS が使える、という話。</p><p>CommonJS は Node とも関係があって、歴史経緯的にクライアントサイドで使われてたけど、サーバーサイドでいろいろやるならこの際モジュール管理とかそういうのしないとだめだよねみたいな話がある。で、それの標準化の提案として CommonJS がある。このときに define と require という<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CD%BD%CC%F3%B8%EC">予約語</a>っぽいのを決めてこう使いましょうという提案がある。で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/AMD">AMD</a> はもうちょっと発展させて CommonJS を発展させて非同期読み込みを実現するための <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> という感じらしい。</p><p>具体的な設定としては参考資料をみながらやった。元のスクリプトが <a class="keyword" href="http://d.hatena.ne.jp/keyword/AMD">AMD</a> どころか Node のモジュールでもないただの JS だったので、こんな感じにした。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink>(<span class="synIdentifier">function</span>(define) <span class="synIdentifier">{</span> <span class="synComment">// id, deps, factory(func or obj)</span> <span class="synComment">// id は省略、依存は特にないので空、モジュールを返すために factory とつける</span> define(<span class="synIdentifier">[]</span>, <span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> <span class="synComment">// てきとうな名前空間をつくってやる</span> <span class="synIdentifier">var</span> _module = <span class="synIdentifier">{}</span>; <span class="synComment">// てきとうな関数を用意してやる</span> <span class="synIdentifier">function</span> pf() <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> tmp = <span class="synIdentifier">arguments[</span>0<span class="synIdentifier">]</span>; <span class="synStatement">for</span> (<span class="synIdentifier">var</span> i=1; i &lt; <span class="synIdentifier">arguments</span>.length; i++) <span class="synIdentifier">{</span> tmp = tmp.replace(<span class="synConstant">/%s/</span>, <span class="synIdentifier">arguments[</span>i<span class="synIdentifier">]</span>); <span class="synIdentifier">}</span> <span class="synStatement">return</span> tmp; <span class="synIdentifier">}</span> <span class="synComment">// モジュールのプロパティに生やしてやる</span> _module.pf = pf; <span class="synComment">// で、最終的にモジュール自体を返してやる</span> <span class="synStatement">return</span> _module; <span class="synIdentifier">}</span>); <span class="synIdentifier">}</span>) ( <span class="synStatement">typeof</span> define !== <span class="synConstant">'undefined'</span> ? <span class="synComment">// AMD 対応していて define がつかえるならそのまま AMD としてつかう</span> define : <span class="synStatement">typeof</span> module !== <span class="synConstant">'undefined'</span> ? <span class="synComment">// If no define, look for module to export as a CommonJS module.</span> <span class="synComment">// で、 module があるのなら Node と判断して module.exports に生やしてやる。</span> <span class="synIdentifier">function</span>(deps, factory) <span class="synIdentifier">{</span> module.exports = factory(); <span class="synIdentifier">}</span> : <span class="synComment">// 最終的にどうもブラウザっぽいならそっちに生やす</span> <span class="synComment">// つまり window.a としてグローバルに生やす</span> <span class="synComment">// for this === window</span> <span class="synIdentifier">function</span>(deps, factory) <span class="synIdentifier">{</span> <span class="synIdentifier">this[</span><span class="synConstant">'a'</span><span class="synIdentifier">]</span> = factory(); <span class="synIdentifier">}</span> ); </pre><p><a href="http://waka.hatenablog.com/entry/2011/11/27/215627">&#x6700;&#x8FD1;&#x306E;JavaScript&#x30E2;&#x30B8;&#x30E5;&#x30FC;&#x30EB;&#x306E;&#x66F8;&#x304D;&#x65B9; - yo_waka&#39;s blog</a><br /> <a href="http://codezine.jp/article/detail/6482">Dojo&#x9053;&#x5834; &#xFF5E; &#x7B2C;11&#x56DE;&#x300C;Dojo &#x6700;&#x65B0;&#x52D5;&#x5411; - Asynchronous Module Definition&#x300D; &#xFF08;1/5&#xFF09;&#xFF1A;CodeZine</a><br /> <div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414813X/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/51yrjFsf-2L._SL160_.jpg" class="hatena-asin-detail-image" alt="パーフェクトJavaScript (PERFECT SERIES 4)" title="パーフェクトJavaScript (PERFECT SERIES 4)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414813X/hatena-blog-22/">パーフェクトJavaScript (PERFECT SERIES 4)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> 井上誠一郎,土江拓郎,浜辺将太</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2011/09/23</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><span class="hatena-asin-detail-label">購入</span>: 24人 <span class="hatena-asin-detail-label">クリック</span>: 586回</li><li><a href="http://d.hatena.ne.jp/asin/477414813X/hatena-blog-22" target="_blank">この商品を含むブログ (12件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p> </div> <div class="section"> <h3>まあ</h3> <p>少なくてもロジックに対してテストができるというのは安心感がある。</p> </div> atasatamatara JavaScript で文字列や日時フォーマットを自前でやる hatenablog://entry/6435922169449643029 2013-03-21T20:15:04+09:00 2013-03-21T20:15:04+09:00 思うところがあったのでやった。基礎練習とか素振りみたいなものです。JavaScript の標準の文字列出力はあまりに貧弱すぎるからそこらへんなんとかなんないかやってみた。ライブラリを使うなら日時フォーマットについては Underscoe.String.js とかあるし、日時は Moment.js あたりがいいらしい。 Underscore.string Moment.js | Parse, validate, manipulate, and display dates in javascript. 文字列の format すごく単純な例 JavaScript テクニックバイブルにあったのを参考… <p>思うところがあったのでやった。基礎練習とか素振りみたいなものです。</p><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> の標準の文字列出力はあまりに貧弱すぎるからそこらへんなんとかなんないかやってみた。ライブラリを使うなら日時フォーマットについては Underscoe.String.js とかあるし、日時は Moment.js あたりがいいらしい。<br /> <a href="http://epeli.github.com/underscore.string/">Underscore.string</a><br /> <a href="http://momentjs.com/">Moment.js | Parse, validate, manipulate, and display dates in javascript.</a></p> <div class="section"> <h3>文字列の format</h3> <div class="section"> <h4>すごく単純な例</h4> <p> <a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> テクニックバイブルにあったのを参考にした。</p><p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774152439/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/516SL6cVQcL._SL160_.jpg" class="hatena-asin-detail-image" alt="JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技" title="JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774152439/hatena-blog-22/">JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> JSサポーターズ</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2012/08/31</li><li><span class="hatena-asin-detail-label">メディア:</span> 単行本(ソフトカバー)</li><li><span class="hatena-asin-detail-label">購入</span>: 38人 <span class="hatena-asin-detail-label">クリック</span>: 1,794回</li><li><a href="http://d.hatena.ne.jp/asin/4774152439/hatena-blog-22" target="_blank">この商品を含むブログ (11件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">function</span> pf() <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> tmp = <span class="synIdentifier">arguments[</span>0<span class="synIdentifier">]</span>; <span class="synStatement">for</span> (<span class="synIdentifier">var</span> i=1; i &lt; <span class="synIdentifier">arguments</span>.length; i++) <span class="synIdentifier">{</span> tmp = tmp.replace(<span class="synConstant">/%s/</span>, <span class="synIdentifier">arguments[</span>i<span class="synIdentifier">]</span>); <span class="synIdentifier">}</span> <span class="synStatement">return</span> tmp; <span class="synIdentifier">}</span> pf(<span class="synConstant">&quot;This %s is %s&quot;</span>, <span class="synConstant">&quot;name&quot;</span>, <span class="synConstant">&quot;ore&quot;</span>) <span class="synComment">// This name is ore</span> </pre><p>やってることは可変長引数をとってやって %s と決め打ちしたところを全部置換してるだけ。arguments[0] で元の文字列を受け取って for ループで i=1 以降を使うことで対応する。というやりかた。</p> </div> <div class="section"> <h4>もうちょっと拡張する - 自作</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> の "string".format(arg) をやってみた。で、似たようなことをやってるような人はそれなりにいたので結局だいぶ参考にしてしまったけど、まずは頭から消してどうにか自前でやってみた。あんまり String とかグローバルなところは拡張したくなかったけど、まあ、習作。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">/**</span> <span class="synComment"> * String.prototype.format</span> <span class="synComment"> * @param String.prototype.arg</span> <span class="synComment"> */</span> <span class="synType">String</span>.prototype.format = <span class="synIdentifier">function</span> (arg) <span class="synIdentifier">{</span> <span class="synComment">// this = String</span> <span class="synIdentifier">var</span> tmp = <span class="synIdentifier">this</span>; <span class="synComment">// Object</span> <span class="synStatement">if</span> (<span class="synStatement">typeof</span> arg === <span class="synConstant">&quot;object&quot;</span>)<span class="synIdentifier">{</span> <span class="synStatement">for</span> (<span class="synIdentifier">var</span> elem <span class="synStatement">in</span> arg)<span class="synIdentifier">{</span> tmp = tmp.replace(<span class="synConstant">&quot;{&quot;</span> + elem + <span class="synConstant">&quot;}&quot;</span>, arg<span class="synIdentifier">[</span>elem<span class="synIdentifier">]</span>); <span class="synIdentifier">}</span> <span class="synComment">// String</span> <span class="synIdentifier">}</span> <span class="synStatement">else</span> <span class="synIdentifier">{</span> <span class="synStatement">for</span> (<span class="synIdentifier">var</span> i=0; i &lt; <span class="synIdentifier">arguments</span>.length; i++) <span class="synIdentifier">{</span> tmp = tmp.replace(<span class="synConstant">&quot;{&quot;</span> + i + <span class="synConstant">&quot;}&quot;</span>, <span class="synIdentifier">arguments[</span>i<span class="synIdentifier">]</span>); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> <span class="synStatement">return</span> tmp; <span class="synIdentifier">}</span>; <span class="synComment">// オブジェクトで渡す</span> <span class="synConstant">&quot;abc {hoge} {moge}&quot;</span>.format(<span class="synIdentifier">{</span>hoge: <span class="synConstant">&quot;text1&quot;</span>, moge: <span class="synConstant">&quot;text2&quot;</span><span class="synIdentifier">}</span>)) <span class="synComment">// abc text1 text2</span> <span class="synComment">// 文字列を複数いれる</span> <span class="synConstant">&quot;abc {0} {1}&quot;</span>.format(<span class="synConstant">&quot;text1&quot;</span>, <span class="synConstant">&quot;text2&quot;</span>); <span class="synComment">// abc text1 text2</span> </pre><p>これもわりと泥臭くて、結局文字列を愚直に組み立てて replace で置換してる。</p> </div> <div class="section"> <h4>もうちょっと拡張する - 参考資料</h4> <p><a href="http://tmlife.net/programming/javascript/javascript-string-format.html">JavaScript &#x3067;&#x6587;&#x5B57;&#x5217;&#x30D5;&#x30A9;&#x30FC;&#x30DE;&#x30C3;&#x30C8;&#x3092;&#x5B9F;&#x88C5;&#x3057;&#x3066;&#x307F;&#x305F;(sprintf &#x3082;&#x3069;&#x304D;) | TM Life</a> のままだけど、変数名はちょっとかえた</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">/**</span> <span class="synComment"> * String.prototype.format2</span> <span class="synComment"> * @param String.prototype.format2arg</span> <span class="synComment"> */</span> <span class="synType">String</span>.prototype.format2 = <span class="synIdentifier">function</span> (arg) <span class="synIdentifier">{</span> <span class="synComment">// init</span> <span class="synIdentifier">var</span> func = <span class="synStatement">null</span>; <span class="synComment">// Object</span> <span class="synStatement">if</span> (<span class="synStatement">typeof</span> arg === <span class="synConstant">&quot;object&quot;</span>)<span class="synIdentifier">{</span> func = <span class="synIdentifier">function</span> (regexp, key) <span class="synIdentifier">{</span><span class="synStatement">return</span> arg<span class="synIdentifier">[</span>key<span class="synIdentifier">]</span>; <span class="synIdentifier">}</span>; <span class="synIdentifier">}</span> <span class="synComment">// String</span> <span class="synStatement">else</span><span class="synIdentifier">{</span> <span class="synComment">// 一度格納しないと末尾しか拾わない</span> <span class="synIdentifier">var</span> args = <span class="synIdentifier">arguments</span>; func = <span class="synIdentifier">function</span> (regexp, key) <span class="synIdentifier">{</span><span class="synStatement">return</span> args<span class="synIdentifier">[</span>key<span class="synIdentifier">]</span>; <span class="synIdentifier">}</span>; <span class="synIdentifier">}</span> <span class="synComment">// this = String</span> <span class="synComment">// replace の第2引数は関数でもよい!</span> <span class="synComment">// そのとき return された文字列をつかう</span> <span class="synComment">// g で繰り返しているから key が増えていく</span> <span class="synStatement">return</span> <span class="synIdentifier">this</span>.replace(<span class="synConstant">/\{(\w+)\}/g</span>, func); <span class="synIdentifier">}</span>; </pre><p>あたまいいなー。なにを知らなかったかというと、 string.repace の第2引数で関数がとれるということ。マッチした第一引数が regexp としてはいってきて、それを args[key] で置き換えてやる。ということをしている。</p> </div> </div> <div class="section"> <h3>簡易日時フォーマット</h3> <p>けっこう泥臭いものをつくった。そのかわり、上で自作した string.format 関数をつかった</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">/**</span> <span class="synComment"> * strftime</span> <span class="synComment"> * @param d</span> <span class="synComment"> */</span> <span class="synIdentifier">function</span> strftime(d) <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> date_format = <span class="synConstant">&quot;{0}年{1}月{2}日:{3}時{4}分{5}秒&quot;</span>.format( d.getFullYear(), d.getMonth() &lt; 10 ? <span class="synConstant">&quot;0&quot;</span> + d.getMonth() : d.getMonth(), d.getDate() &lt; 10 ? <span class="synConstant">&quot;0&quot;</span> + d.getDate() : d.getDate(), d.getHours() &lt; 10 ? <span class="synConstant">&quot;0&quot;</span> + d.getHours() : d.getHours(), d.getMinutes() &lt; 10 ? <span class="synConstant">&quot;0&quot;</span> + d.getMinutes() : d.getMinutes(), d.getSeconds() &lt; 10 ? <span class="synConstant">&quot;0&quot;</span> + d.getSeconds() : d.getSeconds() ); <span class="synStatement">return</span> date_format; <span class="synIdentifier">}</span> <span class="synComment">// strftime(new Date()))</span> <span class="synComment">// &quot;2012年01月02日:03時04分05秒&quot;</span> </pre><p>いいかんじです</p> </div> <div class="section"> <h3>まあ</h3> <p>素振りです。JS の標準機能が貧弱すぎるなら、自分で武器を作れるようにならなくてはいけない。</p> </div> atasatamatara JavaScript 関連のちょっとしたメモ hatenablog://entry/6435922169449645053 2013-03-20T21:03:48+09:00 2013-08-24T00:36:25+09:00 気になって調べたり、見つけたもの。小ネタ。基本的にはmonjudoh/BeautifulProperties.js · GitHub をみてたってのがきっかけ。 prototype 汚染しちゃだめなのって Object と Array だっけ? というか prototype 汚染しないほうがいいのってなんでだっけ?という基礎的な話。prototype.js でいろいろ苦しい話がでたからやめようって経緯があるのは知ってて、名前空間分けようってのは知ってたけど、じゃあどこまでならやっていいんだろうみたいな話。具体的には以下 JavaScriptでのbuilt-in/DOM objectのproto… <p>気になって調べたり、見つけたもの。小ネタ。基本的には<a href="https://github.com/monjudoh/BeautifulProperties.js">monjudoh/BeautifulProperties.js &middot; GitHub</a> をみてたってのがきっかけ。</p> <div class="section"> <h3>prototype 汚染しちゃだめなのって Object と Array だっけ?</h3> <p>というか prototype 汚染しないほうがいいのってなんでだっけ?という基礎的な話。<a class="keyword" href="http://d.hatena.ne.jp/keyword/prototype.js">prototype.js</a> でいろいろ苦しい話がでたからやめようって経緯があるのは知ってて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%BE%C1%B0%B6%F5%B4%D6">名前空間</a>分けようってのは知ってたけど、じゃあどこまでならやっていいんだろうみたいな話。</p><p>具体的には以下<br /> <a href="http://d.hatena.ne.jp/monjudoh/20120904/1346764216">JavaScript&#x3067;&#x306E;built-in/DOM object&#x306E;prototype&#x62E1;&#x5F35; - &#x6587;&#x6B8A;&#x5802;</a></p><p>Object.defineProperty で enumerable: false はしってたけど、なるなるという。</p> </div> <div class="section"> <h3>arguments は array じゃないよって話</h3> <p>答えは本に載ってた</p><p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774152439/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/516SL6cVQcL._SL160_.jpg" class="hatena-asin-detail-image" alt="JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技" title="JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774152439/hatena-blog-22/">JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> JSサポーターズ</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2012/08/31</li><li><span class="hatena-asin-detail-label">メディア:</span> 単行本(ソフトカバー)</li><li><span class="hatena-asin-detail-label">購入</span>: 38人 <span class="hatena-asin-detail-label">クリック</span>: 1,796回</li><li><a href="http://d.hatena.ne.jp/asin/4774152439/hatena-blog-22" target="_blank">この商品を含むブログ (11件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p><p>Array っぽいけどちょっと違う独自のオブジェクトですよという。まあたしかに console.log() した結果で [object Arguments] ってなってたのはみたけど、じゃあなんなの、という状態だった。で、これを配列として扱いたいときは以下のイディオムですよねという。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synType">Array</span>.prototype.slice.apply(<span class="synIdentifier">this</span>, <span class="synIdentifier">arguments</span>) </pre><p>ちなみに上記のイディオムは arguments にたいしてだけじゃなくて Array に変換したいときに一般的にある話で、具体的には DOM で document.getElementsByClassName() とか $(".class") とかしたときにかえってくるのが HTMLCollection とか HTMLElemnt とか NodeList とかそんな感じなので、変換したりする。</p> </div> <div class="section"> <h3>カスタムイベントについて</h3> <p> <a href="http://d.hatena.ne.jp/edvakf/20081219/1229682278">Hit-a-Hint&#x30D6;&#x30C3;&#x30AF;&#x30DE;&#x30FC;&#x30AF;&#x30EC;&#x30C3;&#x30C8;2.0&#x3092;&#x30EA;&#x30EA;&#x30FC;&#x30B9;&#x3057;&#x305F;&#x3088; - by edvakf in hatena</a> を空間ナビゲーション版やエクステンション版や、あるいは vimOperate という拡張でもやれるけど、いまでもつかっている。で、読んだときに「マウスイベント作って→初期化して→発火」というくだりでクリックイベントをエミュレーションできるのだけど、でも <a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>.trigger ってあれどうやってるの?と疑問に思った。</p><p>まずは MDN をあたった<br /> <a href="https://developer.mozilla.org/ja/docs/DOM/document.createEvent">document.createEvent - DOM | MDN</a></p><p>そうだよね、いろいろあるよね。マウスイベントだけじゃなくて DOM 操作や DOM Level 3 Events からはキーボードイベントもとれるよね、いうのはわかった。でもじゃあ自前でイベントをつくるにはどうすればいいんだろう?というのは残った。ら、既にやっている人がいた。</p><p><a href="http://d.hatena.ne.jp/shim0mura/20111224/1324735206">javascript&#x306E;&#x30AB;&#x30B9;&#x30BF;&#x30E0;&#x30A4;&#x30D9;&#x30F3;&#x30C8;&#x3092;&#x4F5C;&#x308D;&#x3046;&#xFF01; - &#x99AC;&#x9E7F;&#x3068;&#x5929;&#x624D;&#x306F;&#x7D19;&#x4E00;&#x91CD;</a></p><p>つまりイベントオブジェクト作ってしまえば名前なんでもよかったのだ。で、リスナーもなんでもよかったのだ。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">// リスナーをはる</span> <span class="synStatement">document</span>.addEventListener(<span class="synConstant">&quot;hoge&quot;</span>,<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(1); <span class="synIdentifier">}</span>, <span class="synConstant">false</span>); <span class="synComment">// イベントオブジェクトつくって</span> <span class="synIdentifier">var</span> e = <span class="synStatement">document</span>.createEvent(<span class="synConstant">&quot;Event&quot;</span>) <span class="synComment">// 初期化して</span> e.initEvent(<span class="synConstant">&quot;hoge&quot;</span>, bubbles, cancelbuble); <span class="synComment">// 対象のエレメントに発火</span> <span class="synStatement">document</span>.dispathEvent(e) <span class="synComment">// 1</span> </pre> </div> <div class="section"> <h3>まあ</h3> <p>小ネタ</p> </div> atasatamatara いまさら JSDeferred と $.Deferred を少しさわったメモ hatenablog://entry/6435922169449636836 2013-03-19T21:12:28+09:00 2013-10-28T22:43:45+09:00 コールバック地獄的なそういうあれを垣間見てしまったので、たしかにもうちょっといいかんじに解決したいってのがよくわかった。そこで書き方を変えることでいい感じに . でチェインしたり例外処理をしやすくするために Deferred がある。ので、簡単なメモとかじったサンプルを張る。あとは以下の記事に触発されたのもある JavaScriptとコールバック地獄 - Yahoo! JAPAN Tech Blog JavaScriptと非同期のエラー処理 - Yahoo! JAPAN Tech Blog 爆速でわかるjQuery.Deferred超入門 - Yahoo! JAPAN Tech Blog 同期… <p>コールバック地獄的なそういうあれを垣間見てしまったので、たしかにもうちょっといいかんじに解決したいってのがよくわかった。そこで書き方を変えることでいい感じに . でチェインしたり例外処理をしやすくするために Deferred がある。ので、簡単なメモとかじったサンプルを張る。</p><p>あとは以下の記事に触発されたのもある<br /> <a href="http://techblog.yahoo.co.jp/programming/js_callback/">JavaScript&#x3068;&#x30B3;&#x30FC;&#x30EB;&#x30D0;&#x30C3;&#x30AF;&#x5730;&#x7344; - Yahoo! JAPAN Tech Blog</a><br /> <a href="http://techblog.yahoo.co.jp/programming/javascript_error/">JavaScript&#x3068;&#x975E;&#x540C;&#x671F;&#x306E;&#x30A8;&#x30E9;&#x30FC;&#x51E6;&#x7406; - Yahoo! JAPAN Tech Blog</a><br /> <a href="http://techblog.yahoo.co.jp/programming/jquery-deferred/">&#x7206;&#x901F;&#x3067;&#x308F;&#x304B;&#x308B;jQuery.Deferred&#x8D85;&#x5165;&#x9580; - Yahoo! JAPAN Tech Blog</a><br /> </p> <div class="section"> <h3>同期と非同期</h3> <p>JS にかぎらず、同期と非同期という考え方がある。処理を逐次行なっていって順番に処理していくのが同期的だとすると、いったんスタックやキューにためておいて「あとでやるからちょっとまって」というように遅延させておくのが非同期処理。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>/Django だと普通に書けば同期的になるけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/celery">celery</a> と RabbitMQ あたりをつかったりさせて非同期処理でバッチさせるというようなことがある(まああとはOS側である程度スレッドつかってくれたりもする)。</p><p>で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> において。発端としてブラウザで動くものとしてあるのでシングルスレッドであると。だから重たい処理をさせるとブラウザが固まる。そうなると困るよね、ってことで、setTimeout とか <a class="keyword" href="http://d.hatena.ne.jp/keyword/XMLHttpRequest">XMLHttpRequest</a> するところあたりでは同期ではなく非同期処理となってる(という理解)。だってブラウザがいろいろ通信してる間に固まったら困るよねっていう。</p><p>たとえば同期的な sleep を実装するとこうなる。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">function</span> sync_sleep(ms) <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> start = <span class="synStatement">new</span> <span class="synType">Date</span>().getTime(); <span class="synIdentifier">var</span> end = start + ms; <span class="synStatement">while</span> (<span class="synConstant">true</span>)<span class="synIdentifier">{</span> <span class="synIdentifier">var</span> tmp = <span class="synStatement">new</span> <span class="synType">Date</span>().getTime(); <span class="synStatement">if</span> (end &lt; tmp)<span class="synIdentifier">{</span> <span class="synStatement">break</span>; <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> <span class="synIdentifier">}</span> </pre><p>でも長いと固まるしブラウザが中断してくるかもしれない。じゃあ非同期にする。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">function</span> async_sleep(ms) <span class="synIdentifier">{</span> setTimeout(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(1); setTimeout(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(2); setTimeout(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(3); setTimeout(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(4); <span class="synIdentifier">}</span>, ms); <span class="synIdentifier">}</span>, ms); <span class="synIdentifier">}</span>, ms); <span class="synIdentifier">}</span>, ms); <span class="synIdentifier">}</span> </pre><p>で、そうすると素直に書くとコールバック関数がネストして眠くなってくる。実際は xhr や $.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ajax">ajax</a> のようなことをネストしたくなったり、あとは Node で本格的に書こうとするとだいぶつらぽよくなってくる</p> </div> <div class="section"> <h3>Deferred の共通の考え方 - callback による非同期処理を簡潔にする</h3> <p>setTimeout(callback, 0) をいれておくことで擬似的にスタックに詰めておくようなことができる。ハック。ブラウザの UI スレッドを止めない。すごい。具体的な資料は以下。はてなの @cho45 さん。2009 年にはやってたことなんだよなぁ。<br /> <a href="https://github.com/cho45/jsdeferred">cho45/jsdeferred &middot; GitHub</a><br /> <a href="http://d.hatena.ne.jp/edvakf/20090414/1239726515">JSDeferred&#x304C;&#x3084;&#x3063;&#x3068;&#x308F;&#x304B;&#x3063;&#x305F; - by edvakf in hatena</a><br /> <a href="http://gihyo.jp/dev/feature/01/jsdeferred">JSDeferred&#x3067;&#xFF0C;&#x9762;&#x5012;&#x306A;&#x975E;&#x540C;&#x671F;&#x51E6;&#x7406;&#x3068;&#x30B5;&#x30E8;&#x30CA;&#x30E9;&#xFF1A;&#x7279;&#x96C6;&#xFF5C;gihyo.jp &hellip; &#x6280;&#x8853;&#x8A55;&#x8AD6;&#x793E;</a></p><p>おぼろげだけどソース読んだりもした。自分の理解としては</p> <ul> <li>Deferred オブジェクトを生成して管理</li> <li>Deferred オブジェクトを起点に処理を next や error でチェインしてかける</li> <li>内部的には next や error ごとに Deferred オブジェクトを生成して管理してやる -> チェインできる</li> </ul><p>というくらいの理解</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/JSDeferred">JSDeferred</a> をちょっとだけかいた</h3> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synIdentifier">var</span> dfd = require(<span class="synConstant">&quot;/path/to/jsdeferred.js&quot;</span>).Deferred; dfd.next(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(1); <span class="synIdentifier">}</span>).wait(1).next(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(2); <span class="synIdentifier">}</span>).wait(1).next(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(3); <span class="synIdentifier">}</span>).wait(1).next(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> <span class="synStatement">throw</span> <span class="synConstant">&quot;throw!&quot;</span>; console.log(4); <span class="synIdentifier">}</span>).error(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(<span class="synConstant">'error'</span>); <span class="synIdentifier">}</span>).next(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(5); <span class="synIdentifier">}</span>).next(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span> console.log(6); <span class="synIdentifier">}</span>); </pre><p>いい感じですね。</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/JSDeferred">JSDeferred</a> と $.Deferred の対比</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/JSDeferred">JSDeferred</a> もあるけど、 <a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>(1.5から)も似たような機能がついた。だいたい似てるけどちょっとまとめる<br /> <a href="http://blog.uu59.org/2011-11-20-jsdeferred-jquery-deferred-1.html">uu59&#x306E;&#x30E1;&#x30E2; | jQuery.Deferred&#x305D;&#x306E;1: JSDeferred&#x3068;&#x306E;&#x57FA;&#x672C;&#x7684;&#x306A;&#x9055;&#x3044;</a><br /> <a href="http://hamalog.tumblr.com/post/5159447047/jquery-deferred">jQuery.Deferred&#x3063;&#x3066;&#x4F55; - Takazudo hamalog</a><br /> <a href="http://d.hatena.ne.jp/aoe-tk/20110515/1305471586">jQuery&#x306E;Deferred&#x30AA;&#x30D6;&#x30B8;&#x30A7;&#x30AF;&#x30C8;&#x306B;&#x3064;&#x3044;&#x3066;&#x8ABF;&#x3079;&#x3066;&#x307F;&#x305F; - AOE&#x306E;&#x65E5;&#x8A18;</a><br /> ちゃんと検証してないけど、自分なりの理解としてはだいたいこんな感じ</p> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/JSDeferred">JSDeferred</a> の next, error に対して <a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>.Deferred の done, fail</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/JSDeferred">JSDeferred</a> の call, fail に対して <a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>.Deferred の resolve, reject</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>.Deferred ではユーザーに状態を変更されないように promise して Deferred オブジェクトを返す</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/JSDeferred">JSDeferred</a> の parallel に対して ちょっとちがうけど <a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>.Deferred では when がある</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>.Deferred だと then で dfd(resolve, reject) とかける</li> </ul><p>まああとは実際に使う機会があったらちゃんとやる。</p> </div> <div class="section"> <h3>まあ</h3> <p>そもそもにおいて setTimeout(callback, 0) という発想がすごい。あとは使う機会があったらちゃんとやる。この手の問題はだいぶ認知されてるみたいで、async系のライブラリは npm とか探すと出てくる。</p> </div> atasatamatara Backbone.js をちょっとだけさわった hatenablog://entry/6435922169449612311 2013-03-18T20:59:31+09:00 2013-03-18T20:59:31+09:00 JS でMVC的に切り分けるということをちょっと学びたかったのですこし触った。具体的に触発されたのはタイミングもあるけど、 フロントエンドJavaScriptにおける設計とテスト をみたってのもある。なにがしたいかって、JS において DOM 操作はともかく、ロジック部分はテストしたいんだよね。テストがないとリファクタリングするときに不安になる。 参考資料 件のスライドの @hokaccha さんの PixelGrid 社の CodeGrid を参考にした。この記事を書いた後にドットインストールの講座が出てきたから、今からだったらそれを見るのもいいかもしれない。 簡単なチュートリアル 面倒なの… <p>JS で<a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>的に切り分けるということをちょっと学びたかったのですこし触った。具体的に触発されたのはタイミングもあるけど、 <a href="http://hokaccha.github.com/slides/javascript_design_and_test/">&#x30D5;&#x30ED;&#x30F3;&#x30C8;&#x30A8;&#x30F3;&#x30C9;JavaScript&#x306B;&#x304A;&#x3051;&#x308B;&#x8A2D;&#x8A08;&#x3068;&#x30C6;&#x30B9;&#x30C8;</a> をみたってのもある。</p><p>なにがしたいかって、JS において DOM 操作はともかく、ロジック部分はテストしたいんだよね。テストがないと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%D5%A5%A1%A5%AF%A5%BF%A5%EA%A5%F3%A5%B0">リファクタリング</a>するときに不安になる。</p> <div class="section"> <h3>参考資料</h3> <p>件のスライドの @hokaccha さんの PixelGrid 社の CodeGrid を参考にした。この記事を書いた後にドットインストールの講座が出てきたから、今からだったらそれを見るのもいいかもしれない。</p> </div> <div class="section"> <h3>簡単なチュートリアル</h3> <p>面倒なので HTML はこんな感じ</p> <pre class="code lang-html" data-lang="html" data-unlink><span class="synComment">&lt;!DOCTYPE html&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">html</span><span class="synIdentifier"> </span><span class="synType">lang</span><span class="synIdentifier">=</span><span class="synConstant">&quot;en&quot;</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">head</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">meta</span><span class="synIdentifier"> </span><span class="synType">charset</span><span class="synIdentifier">=</span><span class="synConstant">&quot;UTF-8&quot;</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">title</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">title</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;./underscore.js&quot;</span><span class="synIdentifier"> </span><span class="synType">charset</span><span class="synIdentifier">=</span><span class="synConstant">&quot;utf-8&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;./jquery-1.7.1.js&quot;</span><span class="synIdentifier"> </span><span class="synType">charset</span><span class="synIdentifier">=</span><span class="synConstant">&quot;utf-8&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;./backbone.js&quot;</span><span class="synIdentifier"> </span><span class="synType">charset</span><span class="synIdentifier">=</span><span class="synConstant">&quot;utf-8&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synPreProc"> </span><span class="synIdentifier">&lt;</span><span class="synStatement">script</span><span class="synIdentifier"> </span><span class="synType">type</span><span class="synIdentifier">=</span><span class="synConstant">&quot;text/javascript&quot;</span><span class="synIdentifier"> </span><span class="synType">src</span><span class="synIdentifier">=</span><span class="synConstant">&quot;./backbone.localStorage.js&quot;</span><span class="synIdentifier"> </span><span class="synType">charset</span><span class="synIdentifier">=</span><span class="synConstant">&quot;utf-8&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">script</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">head</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;</span><span class="synStatement">body</span><span class="synIdentifier">&gt;</span> backbone.js! <span class="synIdentifier">&lt;</span><span class="synStatement">ul</span><span class="synIdentifier"> </span><span class="synType">class</span><span class="synIdentifier">=</span><span class="synConstant">&quot;todoList&quot;</span><span class="synIdentifier">&gt;&lt;/</span><span class="synStatement">ul</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">body</span><span class="synIdentifier">&gt;</span> <span class="synIdentifier">&lt;/</span><span class="synStatement">html</span><span class="synIdentifier">&gt;</span> </pre><p>で、肝心の内容。本当は通信もみてみたかったけど、サーバーたてるの面倒なので backbone.localStorage を使用した。</p> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synComment">// model の生成</span> <span class="synIdentifier">var</span> Todo = Backbone.Model.extend(<span class="synIdentifier">{</span> name: <span class="synStatement">null</span>, localStorage: <span class="synStatement">new</span> Store(<span class="synConstant">&quot;todos&quot;</span>) <span class="synIdentifier">}</span>); <span class="synComment">// model の集合である collection を生成</span> <span class="synIdentifier">var</span> Todos = Backbone.Collection.extend(<span class="synIdentifier">{</span> model: Todo <span class="synIdentifier">}</span>); <span class="synComment">// model のインスタンスを生成</span> <span class="synIdentifier">var</span> todo1 = <span class="synStatement">new</span> Todo(<span class="synIdentifier">{</span>name: <span class="synConstant">'hoge'</span><span class="synIdentifier">}</span>); <span class="synIdentifier">var</span> todo2 = <span class="synStatement">new</span> Todo(<span class="synIdentifier">{</span>name: <span class="synConstant">'moge'</span><span class="synIdentifier">}</span>); <span class="synIdentifier">var</span> todo3 = <span class="synStatement">new</span> Todo(<span class="synIdentifier">{</span>name: <span class="synConstant">'toge'</span><span class="synIdentifier">}</span>); <span class="synIdentifier">var</span> todo4 = <span class="synStatement">new</span> Todo(<span class="synIdentifier">{</span>name: <span class="synConstant">'ea'</span><span class="synIdentifier">}</span>); <span class="synComment">// collection のインスタンスを生成</span> <span class="synIdentifier">var</span> todos = <span class="synStatement">new</span> Todos(); <span class="synComment">// collection に model をつめこむ</span> todos.add(<span class="synIdentifier">[</span>todo1, todo2, todo3, todo4<span class="synIdentifier">]</span>); <span class="synComment">// UI コンポーネントと考えるといい。これは子要素の li タグ</span> <span class="synIdentifier">var</span> TodoListItem = Backbone.View.extend(<span class="synIdentifier">{</span> tagName: <span class="synConstant">'li'</span>, <span class="synComment">// options ってつけるのが慣習っぽいけど、中身は object(dict) だよねっていう</span> initialize: <span class="synIdentifier">function</span> (object) <span class="synIdentifier">{</span> <span class="synComment">// で、object のプロパティを指定して加える</span> <span class="synIdentifier">this</span>.$el.text(object.text); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>); <span class="synComment">// こっちは親要素の ul をとってくる</span> <span class="synIdentifier">var</span> TodoList = Backbone.View.extend(<span class="synIdentifier">{</span> el: <span class="synConstant">'.todoList'</span>, add: <span class="synIdentifier">function</span> (text) <span class="synIdentifier">{</span> <span class="synComment">// {text: text} ってのも微妙だけど、text プロパティに引数 text を加えるという話</span> <span class="synIdentifier">var</span> item = <span class="synStatement">new</span> TodoListItem(<span class="synIdentifier">{</span>text: text<span class="synIdentifier">}</span>); <span class="synIdentifier">this</span>.$el.append(item.el); <span class="synIdentifier">}</span>, collection: todos <span class="synIdentifier">}</span>); <span class="synComment">// View のインスタンスを生成する</span> <span class="synIdentifier">var</span> todolist = <span class="synStatement">new</span> TodoList(); todolist.add(<span class="synConstant">'a'</span>); todolist.add(<span class="synConstant">'b'</span>); todolist.add(<span class="synConstant">'c'</span>); todolist.add(<span class="synConstant">'c'</span>); <span class="synIdentifier">var</span> TodoList = Backbone.View.extend(<span class="synIdentifier">{</span> initialize: <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span> <span class="synIdentifier">this</span>.collection.on(<span class="synConstant">'add'</span>, <span class="synIdentifier">this</span>.add, <span class="synIdentifier">this</span>); <span class="synIdentifier">}</span>, add: <span class="synIdentifier">function</span>(todo) <span class="synIdentifier">{</span> <span class="synIdentifier">var</span> item = <span class="synStatement">new</span> TodoListItem(<span class="synIdentifier">{</span> model: todo <span class="synIdentifier">}</span>); <span class="synIdentifier">this</span>.$el.append(item.el); <span class="synIdentifier">}</span> <span class="synIdentifier">}</span>); </pre> </div> <div class="section"> <h3>雑感</h3> <p>Sencha Touch をガリガリやってて、「ああそういうことか」ってのが腑に落ちた。感覚としては「model, collection でデータを扱う。View で UI <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>を生成する。それぞれは分離している」という感じ。だから<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C2%B7%EB%B9%E7">疎結合</a>にしやすい。ということなんだろう。</p><p>Event と Router は調べたけど触ってはいない。ただ、history.pushState とかつかっていい感じにしてくれるのは楽そうだね。</p> </div> <div class="section"> <h3>ちなみに</h3> <p>Sencha Touch で <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ajax">Ajax</a> 通信してしまうとき idProperty がついてしまったりしてそれが <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> 仕様とあわなかったりするのは Backbone.js でもある話で、通信部分の URL の組み立ては結局自前でやる必要があったりする。GET, POST はいいけど PUT, DELETE とかを使うか否かってのもオプションにある。</p><p>あと AugularJS についてもちょっとだけドットインストールでみたりした。あれはもうちょっとライトな<a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>のかたちなんだろうか?個人的には JSON 受け取ったら組み立てるだけって感じで、たしかにお手軽なんだけど本格的にサイトを組もうとすると大変そう。逆に言うと単純なサイトをお手軽につくるときには楽そう。</p> </div> <div class="section"> <h3>まあ</h3> <p>Backbone.js をつかって仕事する機会はそんなにないと思うけど、得るものはあったなという感じ</p> </div> atasatamatara reStructuredText 用の簡単なスニペットをつくった hatenablog://entry/13425511277527040897 2013-03-17T20:35:33+09:00 2013-10-16T19:47:25+09:00 wiki や Redmine も markdown ではなくて reST だし、Sphinx つかうこともあるのでだいたい reST を使っている。プライベートや各種メモも Dropbox に todo.rst や anken.rst みたいな感じで管理してる。で、 riv.vim は高機能だけどちょっと面倒だし*1、なんかもっとてきとうに reST をかけないか。 探したけど 断片的になくはなかったが流用できるほどかというと微妙だった。Sublime Text 2 用にすこしあったけど、まあ今回は違うし。なくはなかったけど微妙だったのでてきとうにつくった。 前提 neocomplecache… <p>wiki や <a class="keyword" href="http://d.hatena.ne.jp/keyword/Redmine">Redmine</a> も markdown ではなくて reST だし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Sphinx">Sphinx</a> つかうこともあるのでだいたい reST を使っている。プライベートや各種メモも <a class="keyword" href="http://d.hatena.ne.jp/keyword/Dropbox">Dropbox</a> に todo.rst や anken.rst みたいな感じで管理してる。で、 riv.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> は高機能だけどちょっと面倒だし<a href="#f1" name="fn1" title="いちおうシンタックスに rest.vim はいれてはみている">*1</a>、なんかもっとてきとうに reST をかけないか。</p> <div class="section"> <h3>探したけど</h3> <p>断片的になくはなかったが流用できるほどかというと微妙だった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Sublime">Sublime</a> Text 2 用にすこしあったけど、まあ今回は違うし。なくはなかったけど微妙だったのでてきとうにつくった。</p> </div> <div class="section"> <h3>前提</h3> <p>neocomplecache + neosnippet です</p> </div> <div class="section"> <h3>こんなの</h3> <p>たいした話ではない</p> <pre class="code" data-unlink>snippet quickstart abbr quickstart prev_word &#39;^&#39; =========================== ${1:content_name} =========================== .. content :: ${1:content_name} title1 ==================================== subtitle1 ----------------------------------- subtitle2 ----------------------------------- subtitle3 ----------------------------------- title2 ==================================== subtitle1 ----------------------------------- subtitle2 ----------------------------------- subtitle3 ----------------------------------- title3 ==================================== subtitle1 ----------------------------------- subtitle2 ----------------------------------- subtitle3 ----------------------------------- snippet contnents abbr contents prev_word &#39;^&#39; .. Contents :: ${1:contents_name} snippet title abbr title prev_word &#39;^&#39; ${1:title} ==================================== snippet subtitle abbr subtitle prev_word &#39;^&#39; ${1:subtitle} ----------------------------------- snippet code abbr code-block prev_word &#39;^&#39; .. code-block :: ${1:python} ${2:content} snippet link_raw abbr link_as_raw prev_word &#39;^&#39; \`${1:link}\`_ snippet link abbr link_and_label prev_word &#39;^&#39; \`${1:title} &lt;${2:link}&gt;\`_ snippet table_grid abbr grid_table prev_word &#39;^&#39; +------------------+------------+-----------------------+------------+ |${1:cel} | | | | +==================+============+=======================+============+ | | | | | +------------------+------------+-----------------------+------------+ | | | | | +------------------+------------+-----------------------+------------+ snippet field_list abbr field_list prev_word &#39;^&#39; :${1:text} : : : : : : : snippet list abbr list prev_word &#39;^&#39; - - - - snippet nested_list abbr nested_list prev_word &#39;^&#39; - ${1:text} - - - snippet caption abbr caption prev_word &#39;^&#39; [#] snippet image abbr image prev_word &#39;^&#39; .. image :: ${1:path} snippet strong abbr strong prev_word &#39;^&#39; **${1:text}** </pre><p>コピペでもいいけど、だいたい議事録とかはじめにかくテンプレートってのが決まってれば全部スニペットにしてしまえばよい、という話。それっぽいものができるので、あとは議事録でもリストでも見出しでも書けばいい。</p> </div> <div class="section"> <h3>ついでに</h3> <p><a href="https://github.com/Shougo/junkfile.vim">Shougo/junkfile.vim &middot; GitHub</a> というのをいれた。コマンド一発で使い捨てで rst ファイルを呼び出して作ってしまえばいい。で、<a href="http://atasatamatara.hatenablog.jp/entry/2013/03/07/215806">Vim &#x3067; tmux &#x3067; CUI &#x74B0;&#x5883;&#x306E; Ubuntu Server &#x3067;&#x3082;&#x3068;&#x306B;&#x304B;&#x304F;&#x30B3;&#x30D4;&#x30DA;&#x304C;&#x3057;&#x305F;&#x3044; - &#x61A7;&#x308C;&#x99C6;&#x52D5;&#x958B;&#x767A;</a> で書いたようにコピーしてしまえばいいし、Unite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> はつかっているので履歴から呼び出せばよい。</p> <div class="section"> <h4>ほんとうは</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a> で(?:Vimperator|Pentactygl)外部エディタ呼び出ししてやるか、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>でも同じようなことができなくはないのでやるかするといい。とはいえ、宗教上の理由で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a>だし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a> Extension は <a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a> や <a class="keyword" href="http://d.hatena.ne.jp/keyword/Safari">Safari</a> と似ているとはいえまあ面倒なのでそこまではやっていない。赤福さんって人の wasavi っていうテキストエリアを <a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> 風に編集できる拡張もそれはそれでいいのだけど、やっぱり高機能な外部エディタを使いたい。</p> </div> </div> <div class="section"> <h3>まあ</h3> <p>入力補完はテンプレートとかジェネレーターみたいな感じでどんどんやれるほうが好きだし、このスニペット自体の作成は20分くらいの作業でできることなのでよい。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">いちおうシンタックスに rest.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> はいれてはみている</span></p> </div> atasatamatara Sphinx で日本語を含む PDF 出力をする hatenablog://entry/6435922169449608414 2013-03-16T20:42:32+09:00 2013-08-23T22:18:54+09:00 PDF を納める必要があったのでやった。Sphinx というか reST での日本語出力には若干の難があるらしい。けど、これも先人のとおりにやったら簡単にできた。 rst2pdf 方式 (8日目) Sphinx から PDF を生成してみよう (rst2pdf 編) - Hack like a rolling stone をまず参考にやってみた。pip install rst2pdf, PIL 環境構築, VLゴシックのようなフォントをいれる。 ja.json を作成して読み込ませる。PIL 環境の構築はハマりやすいから http://atasatamatara.hatenablog.jp/e… <p>PDF を納める必要があったのでやった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Sphinx">Sphinx</a> というか reST での日本語出力には若干の難があるらしい。けど、これも先人のとおりにやったら簡単にできた。</p> <div class="section"> <h3>rst2pdf 方式</h3> <p><a href="http://tk0miya.hatenablog.com/entry/20111208/p1">(8&#x65E5;&#x76EE;) Sphinx &#x304B;&#x3089; PDF &#x3092;&#x751F;&#x6210;&#x3057;&#x3066;&#x307F;&#x3088;&#x3046; (rst2pdf &#x7DE8;) - Hack like a rolling stone</a> をまず参考にやってみた。pip install rst2pdf, PIL 環境構築, <a class="keyword" href="http://d.hatena.ne.jp/keyword/VL%A5%B4%A5%B7%A5%C3%A5%AF">VLゴシック</a>のようなフォントをいれる。 ja.json を作成して読み込ませる。PIL 環境の構築はハマりやすいから <a href="http://atasatamatara.hatenablog.jp/entry/20120803/1344001904">http://atasatamatara.hatenablog.jp/entry/20120803/1344001904</a> を参考にするといい。</p><p>結果としてはうまくいかなかった。後述の日本語のなんらかのパッチのはいった <a class="keyword" href="http://d.hatena.ne.jp/keyword/Sphinx">Sphinx</a> だったらできたかもしれないけど、一部が文字化けした。あと、後述の <a class="keyword" href="http://d.hatena.ne.jp/keyword/latex">latex</a> 経由のほうが印刷物としてのオプションが豊富でいい感じだった。</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/LaTeX">LaTeX</a> 経由で PDF 出力</h3> <p><a href="http://tk0miya.hatenablog.com/entry/20111211/p1">(11&#x65E5;&#x76EE;) Sphinx &#x304B;&#x3089; PDF &#x3092;&#x751F;&#x6210;&#x3057;&#x3066;&#x307F;&#x3088;&#x3046; (LaTeX &#x7DE8;) - Hack like a rolling stone</a> と <a href="http://sphinx-users.jp/cookbook/pdf/latex.html">LaTeX&#x7D4C;&#x7531;&#x3067;&#x306E;PDF&#x4F5C;&#x6210; :: &#x30C9;&#x30AD;&#x30E5;&#x30E1;&#x30F3;&#x30C6;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x30C4;&#x30FC;&#x30EB; &#x30B9;&#x30D5;&#x30A3;&#x30F3;&#x30AF;&#x30B9; Sphinx-users.jp</a> を参考にした。</p> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/TeX">TeX</a> 環境の構築</h4> <p>Mac なので MacTeX を導入した。若干重い。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a> なら LiveTex2011 あたりとからしい。Windwosはよくわからないけど、それっぽいのがあるらしい。</p><p>インストールしたらアップデートも必要。これもわりと時間がかかる。</p> <pre class="code lang-sh" data-lang="sh" data-unlink>sudo tlmgr update <span class="synSpecial">--self</span> sudo tlmgr update <span class="synSpecial">--all</span> </pre> </div> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/TeX">TeX</a> 関係の PATH を通す</h4> <p>そのまま。上記の記事だと2011年で若干違ったりするから、適宜置き換え。今回は2012年だった。</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synStatement">export</span><span class="synIdentifier"> PATH=</span><span class="synPreProc">$PATH</span>:/usr/<span class="synStatement">local</span>/texlive/<span class="synConstant">2012</span>/bin/universal-darwin </pre> </div> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/Sphinx">Sphinx</a> PDF 出力日本語パッチ済みのものをダウンロードする</h4> <p>ありがたや</p> <pre class="code lang-sh" data-lang="sh" data-unlink>pip uninstall Sphinx pip <span class="synStatement">install</span> https://bitbucket.org/sphinxjp/website/downloads/Sphinx<span class="synConstant">-1</span>.<span class="synConstant">1</span>.3sphinxjp-latex.tar.gz </pre> </div> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/Sphinx">Sphinx</a> の conf.py の設定</h4> <p>以下を設定する</p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synComment"># 言語の設定</span> language = <span class="synConstant">'ja'</span> <span class="synComment"># LaTeX の docclass 設定</span> latex_docclass = {<span class="synConstant">'manual'</span>: <span class="synConstant">'jsbook'</span>} </pre> </div> <div class="section"> <h4>build!</h4> <pre class="code lang-sh" data-lang="sh" data-unlink>make latexpfja </pre><p>これで _build/<a class="keyword" href="http://d.hatena.ne.jp/keyword/latex">latex</a>/ 以下にPDFが出力される</p> </div> <div class="section"> <h4>継続的ビルド</h4> <p><a href="http://atasatamatara.hatenablog.jp/entry/2013/03/15/200115">Sphinx &#x306E;&#x30D3;&#x30EB;&#x30C9;&#x3092;&#x30D5;&#x30A1;&#x30A4;&#x30EB;&#x76E3;&#x8996;&#x3057;&#x3066;&#x81EA;&#x52D5;&#x3067;&#x884C;&#x3046;</a> と同じ要領でファイル更新のたびにプレビュー</p> <pre class="code lang-python" data-lang="python" data-unlink>watchmedo shell-command --patterns=<span class="synConstant">&quot;*.rst&quot;</span> --recursive --command=<span class="synConstant">'make latexpdfja'</span> </pre><p>とてもよい</p> </div> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/LaTeX">LaTeX</a> のオプション</h4> <p>印刷物としてそれっぽくいいかんじに出力するためには <a href="http://sphinx-users.jp/doc11/config.html">&#x30D3;&#x30EB;&#x30C9;&#x8A2D;&#x5B9A;&#x30D5;&#x30A1;&#x30A4;&#x30EB;(conf.py) &mdash; Sphinx 1.1 (hg) documentation</a> を参考にするといい。ページの改行とか、脚注とか、そういうオプションが豊富にあるので適宜設定する。</p> </div> </div> <div class="section"> <h3>まあ</h3> <p>かなしみの Word や Excel 仕様書じゃなくて <a class="keyword" href="http://d.hatena.ne.jp/keyword/Sphinx">Sphinx</a> によるよろこびの仕様書、よい。あと、仕様書もHTMLで十分じゃんと思ってたけど、なんかこう綺麗なPDFってちょっとうれしい感ある。</p> </div> atasatamatara Sphinx のビルドをファイル監視して自動で行う hatenablog://entry/6435922169449608353 2013-03-15T20:01:15+09:00 2013-08-23T22:19:22+09:00 Sphinx でドキュメントを書く必要があったので、せっかくなので make html をいちいち手打ちしないで自動でビルドするようにした。 先人はいる ファイル監視してスクリプトってのはまあある話で、Python なら watchdog というのが使えるようだ。 参考 watchdogモジュールのwatchmedoコマンドが便利 - 偏った言語信者の垂れ流し omakeもmakeも使わずに、Sphinxドキュメントの継続的ビルド - Study08.net 対シンバシ殲滅用人型機動兵器 pip install watchdog watchmedo shell-command --patter… <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Sphinx">Sphinx</a> でドキュメントを書く必要があったので、せっかくなので make html をいちいち手打ちしないで自動でビルドするようにした。</p> <div class="section"> <h3>先人はいる</h3> <p>ファイル監視してスクリプトってのはまあある話で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> なら watchdog というのが使えるようだ。<br /> 参考<br /> <a href="http://d.hatena.ne.jp/nullpobug/20120331/1333125058">watchdog&#x30E2;&#x30B8;&#x30E5;&#x30FC;&#x30EB;&#x306E;watchmedo&#x30B3;&#x30DE;&#x30F3;&#x30C9;&#x304C;&#x4FBF;&#x5229; - &#x504F;&#x3063;&#x305F;&#x8A00;&#x8A9E;&#x4FE1;&#x8005;&#x306E;&#x5782;&#x308C;&#x6D41;&#x3057;</a><br /> <a href="http://tell-k.hatenablog.com/entry/2012/01/04/022229">omake&#x3082;make&#x3082;&#x4F7F;&#x308F;&#x305A;&#x306B;&#x3001;Sphinx&#x30C9;&#x30AD;&#x30E5;&#x30E1;&#x30F3;&#x30C8;&#x306E;&#x7D99;&#x7D9A;&#x7684;&#x30D3;&#x30EB;&#x30C9; - Study08.net &#x5BFE;&#x30B7;&#x30F3;&#x30D0;&#x30B7;&#x6BB2;&#x6EC5;&#x7528;&#x4EBA;&#x578B;&#x6A5F;&#x52D5;&#x5175;&#x5668;</a></p> <pre class="code lang-sh" data-lang="sh" data-unlink>pip <span class="synStatement">install</span> watchdog watchmedo shell-command <span class="synSpecial">--patterns=</span><span class="synStatement">&quot;</span><span class="synConstant">*.rst</span><span class="synStatement">&quot;</span> <span class="synSpecial">--recursive</span> <span class="synSpecial">--command=</span><span class="synStatement">'</span><span class="synConstant">make html</span><span class="synStatement">'</span> <span class="synComment"># あるいは</span> watchmedo shell-command <span class="synSpecial">-p</span><span class="synStatement">=&quot;</span><span class="synConstant">*.rst</span><span class="synStatement">&quot;</span> <span class="synSpecial">-R</span> <span class="synSpecial">-c</span><span class="synStatement">=&quot;</span><span class="synConstant">make html</span><span class="synStatement">&quot;</span> </pre><p>なんてことはない話ですね。</p> </div> <div class="section"> <h3>で、できると思った?</h3> <p>残念さやかちゃんでした!</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> だとファイル更新が検知されない</h3> <p>VimFiler で新規作成したときは検知されて更新がはしるけど、ファイル保存時には検知されない。で、ちょっと聞いてみると <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> 特有の問題で他のエディターだと問題がなかった。たとえば、CotEditor だと特に問題なく検知され更新が走った。</p><p>これの問題は <a href="https://github.com/gorakhargosh/watchdog#about-using-watchdog-with-editors-like-vim">gorakhargosh/watchdog &middot; GitHub</a> にあった。</p> <blockquote> <p>About using watchdog with editors like <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a></p><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> does not modify files unless directed to do so. It creates backup files and then swaps them in to replace the files you are editing on the disk. This means that if you use <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> to edit your files, the on-modified events for those files will not be triggered by watchdog. You may need to configure <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> to appropriately to disable this feature.</p> </blockquote> <p>「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> だとバックアップファイルの関係でファイル編集イベントが拾えないよ。だからなんか <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> の設定を無効にしてね」とある。でも set nobackup set noswapfile はしている。つまり、スワップファイルもバックアップファイルもつくらないようにしている。なぜだろう。さがした。あった。</p><p><a href="http://stackoverflow.com/questions/7591527/writing-a-file-with-vim-doesnt-fire-a-file-change-event-on-os-x">python - Writing a file with vim doesn&#39;t fire a file change event on OS X - Stack Overflow</a></p><p>ということで、以下のようになった</p> <pre class="code lang-vim" data-lang="vim" data-unlink><span class="synStatement">set</span> <span class="synPreProc">noswapfile</span> <span class="synStatement">set</span> <span class="synPreProc">nobackup</span> <span class="synStatement">set</span> <span class="synPreProc">nowritebackup</span> </pre> </div> <div class="section"> <h3>まあ</h3> <p>勝手にビルドしてくれるのはすごい楽ですね</p> </div> atasatamatara hg log の出力をもうちょっといい感じに整形する hatenablog://entry/6435922169449604097 2013-03-14T20:19:51+09:00 2013-03-14T20:19:51+09:00 Feb とか Fri とかわかんない いまのところこんなかんじの .hgrc をつかっていて、あまり不自由はなかった。 [ui] username = atasatamatara editor = vim [extensions] color = graphlog = pager = [color] status.modified = magenta bold status.added = green bold status.removed = red bold status.deleted = cyan bold status.unknown = blue bold status.ignor… <div class="section"> <h3>Feb とか Fri とかわかんない</h3> <p>いまのところこんなかんじの .hgrc をつかっていて、あまり不自由はなかった。</p> <pre class="code lang-cfg" data-lang="cfg" data-unlink><span class="synType">[ui]</span> <span class="synStatement">username </span>=<span class="synConstant"> atasatamatara</span> <span class="synStatement">editor </span>=<span class="synConstant"> vim</span> <span class="synType">[extensions]</span> <span class="synStatement">color </span>= <span class="synStatement">graphlog </span>= <span class="synStatement">pager </span>= <span class="synType">[color]</span> <span class="synStatement">status.modified </span>=<span class="synConstant"> magenta bold</span> <span class="synStatement">status.added </span>=<span class="synConstant"> green bold</span> <span class="synStatement">status.removed </span>=<span class="synConstant"> red bold</span> <span class="synStatement">status.deleted </span>=<span class="synConstant"> cyan bold</span> <span class="synStatement">status.unknown </span>=<span class="synConstant"> blue bold</span> <span class="synStatement">status.ignored </span>=<span class="synConstant"> black bold</span> <span class="synStatement">diff.diffline </span>=<span class="synConstant"> bold</span> <span class="synStatement">diff.extended </span>=<span class="synConstant"> cyan bold</span> <span class="synStatement">diff.file_a </span>=<span class="synConstant"> red bold</span> <span class="synStatement">diff.file_b </span>=<span class="synConstant"> green bold</span> <span class="synStatement">diff.hunk </span>=<span class="synConstant"> magenta</span> <span class="synStatement">diff.deleted </span>=<span class="synConstant"> red</span> <span class="synStatement">diff.inserted </span>=<span class="synConstant"> green</span> <span class="synStatement">diff.changed </span>=<span class="synConstant"> white</span> <span class="synStatement">diff.trailingwhitespace </span>=<span class="synConstant"> bold red_background</span> <span class="synType">[pager]</span> <span class="synStatement">pager = LESS</span>=<span class="synConstant">'FSRX' less</span> %include ~/.hgrc.local </pre><p>だいたいいいんだけど、hg log とか hg glog したときに日付のフォーマットが Fri, 2013, みたいなそういう形式なのがちょっと嫌でどうにか整形できないかと思った。考えてみれば <a class="keyword" href="http://d.hatena.ne.jp/keyword/mercurial">mercurial</a> なんだし <a class="keyword" href="http://d.hatena.ne.jp/keyword/python">python</a> で、 datetime を strftime すればいいんじゃね?と思って調べた。<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a> ツール使えってのもいいが、おれは <a class="keyword" href="http://d.hatena.ne.jp/keyword/CUI">CUI</a> で完結させるほうが好きなんです。</p> </div> <div class="section"> <h3>style と template についての資料</h3> <p>hg log --template {string} か、そのテンプレートになったファイル hg log --style {PATH} でできる。具体的な参考資料は以下。<br /> style について <a href="http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html">Chapter 11. Customizing the output of Mercurial</a><br /> template の設定サンプル <a href="http://yuitowest.hatenablog.com/entry/20110610/1307697282">mercurial&#x306E;style&#x3092;&#x4F7F;&#x7528;&#x3057;&#x3066;log&#x51FA;&#x529B;&#x3092;&#x30AB;&#x30B9;&#x30BF;&#x30DE;&#x30A4;&#x30BA;&#x3059;&#x308B; - yuitowest&#39;s blog</a><br /> 具体的な設定の公式資料は hg help templating で確認できる。<br /> また、具体的な設定項目についての日本語訳してくれているものがある。 <a href="http://foozy.bitbucket.org/hgbook-ja/d6ca1334a19d/hgbookch11.html">11 Customising the output of Mercurial</a></p> </div> <div class="section"> <h3>色設定について</h3> <p>以下を参考にした。<br /> <a href="http://yonchu.hatenablog.com/entry/2012/10/20/044603">bash/zsh&#x3067;16&#x8272;(ANSI &#x30AB;&#x30E9;&#x30FC;&#x30B3;&#x30FC;&#x30C9;)&#x3068;256&#x8272;&#x306E;&#x30AB;&#x30E9;&#x30FC;&#x30D1;&#x30EC;&#x30C3;&#x30C8;&#x3092;&#x8868;&#x793A; - &#x3088;&#x3093;&#x3061;&#x3085;Blog</a></p> </div> <div class="section"> <h3>.hgrc で読み込ませる設定について</h3> <p><a href="http://stackoverflow.com/questions/5085886/mercurial-where-to-put-the-style-file-so-it-can-easily-be-used-on-all-my-pr">Mercurial: where to put the &quot;style file&quot; so it can (easily) be used on all my projects - Stack Overflow</a> を参考にした。</p> <pre class="code lang-cfg" data-lang="cfg" data-unlink><span class="synType">[ui]</span> <span class="synStatement">style </span>=<span class="synConstant"> path/to/mystyle</span> </pre> </div> <div class="section"> <h3>自分がやった具体的な設定</h3> <p>最終的にこんな感じになった</p> <pre class="code lang-cfg" data-lang="cfg" data-unlink><span class="synStatement">changeset </span>=<span class="synConstant"> '\033[0;33mchengeset : {rev}:{node|short} {tags}\033[0m\nsummary : {desc|firstline|strip}\nuser : {author}\nbranch : {branch}\ndate : {date|isodate} : {date|age}\n{file_adds}\n{file_dels}\n{file_mods}\n\n'</span> <span class="synStatement">start_file_adds </span>=<span class="synConstant"> '\n'</span> <span class="synStatement">file_add </span>=<span class="synConstant"> '\033[0;31mA {file_add}\033[0m\n'</span> <span class="synComment"># end_file_adds = ''</span> <span class="synComment"># start_file_dels = ''</span> <span class="synStatement">file_del </span>=<span class="synConstant"> '\033[0;31mR {file_del}\033[0m\n'</span> <span class="synComment"># end_file_dels = ''</span> <span class="synComment"># start_file_mods = ''</span> <span class="synStatement">file_mod </span>=<span class="synConstant"> '\033[0;35mM {file_mod}\033[0m\n'</span> <span class="synComment"># end_file_mods = ''</span> </pre><p>とりあえず日時フォーマットを {date|isodate}して {date|age}そのコミットが何時間前かの表示を追加、branch も常に表示するようにした。ついでにファイルの add, remove, modified したのも表示されるようにした。どのファイルが更新されるかみれるというのは、誰がどのブランチでどのファイルを触ったかがわかりやすくて動きが見えやすくていい。そのかわり気持ちちょっと重くなった。hg log --limit 10 とかしてもかわらない。まあ、気持ちの問題としていまはまあいいやという。</p> </div> <div class="section"> <h3>まあ</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a> ツールつかえば簡単かもだけど、自分としてはかねがね満足。もうすこしいえば diff まわりでもっと簡単に楽にみれるようにしたいけど、まあ、いまはいいや。</p> <div class="section"> <h4>ここまでかいたけど</h4> <p>hgview って git の tig みたいなものもあるんですね……</p> </div> </div> atasatamatara AWS の EC2 と S3 をちょっとさわった hatenablog://entry/6435988827675845042 2013-03-13T20:26:54+09:00 2013-03-13T20:26:55+09:00 目的はある特定の数日間だけサーバーが欲しいということだったんだけど、いろいろ流れて使わないことになった。でもまあ AWS のさわりくらいやっておこう。というメモ。 ざっくりとした理解 とりあえず公式やそれに準じるドキュメントを読めばだいたいわかる。あとはググれば導入くらいの話はわりとある。 アマゾン ウェブ サービス | クラウド プラットフォーム活用を支援する Amazon の Iaas, Paas 型クラウド (AWS 日本語) Amazon EC2 (仮想サーバー Amazon Elastic Compute Cloud) | アマゾン ウェブ サービス(AWS 日本語) AWSのはじめ… <p>目的はある特定の数日間だけサーバーが欲しいということだったんだけど、いろいろ流れて使わないことになった。でもまあ AWS のさわりくらいやっておこう。というメモ。</p> <div class="section"> <h3>ざっくりとした理解</h3> <p>とりあえず公式やそれに準じるドキュメントを読めばだいたいわかる。あとはググれば導入くらいの話はわりとある。<br /> <a href="http://aws.amazon.com/jp/">&#x30A2;&#x30DE;&#x30BE;&#x30F3; &#x30A6;&#x30A7;&#x30D6; &#x30B5;&#x30FC;&#x30D3;&#x30B9; | &#x30AF;&#x30E9;&#x30A6;&#x30C9; &#x30D7;&#x30E9;&#x30C3;&#x30C8;&#x30D5;&#x30A9;&#x30FC;&#x30E0;&#x6D3B;&#x7528;&#x3092;&#x652F;&#x63F4;&#x3059;&#x308B; Amazon &#x306E; Iaas, Paas &#x578B;&#x30AF;&#x30E9;&#x30A6;&#x30C9; (AWS &#x65E5;&#x672C;&#x8A9E;&#xFF09;</a><br /> <a href="http://aws.amazon.com/jp/ec2/">Amazon EC2 (&#x4EEE;&#x60F3;&#x30B5;&#x30FC;&#x30D0;&#x30FC; Amazon Elastic Compute Cloud) | &#x30A2;&#x30DE;&#x30BE;&#x30F3; &#x30A6;&#x30A7;&#x30D6; &#x30B5;&#x30FC;&#x30D3;&#x30B9;&#xFF08;AWS &#x65E5;&#x672C;&#x8A9E;&#xFF09;</a><br /> <a href="http://aws.amazon.com/jp/aws-first-step/">AWS&#x306E;&#x306F;&#x3058;&#x3081;&#x304B;&#x305F; | &#x30A2;&#x30DE;&#x30BE;&#x30F3; &#x30A6;&#x30A7;&#x30D6; &#x30B5;&#x30FC;&#x30D3;&#x30B9;&#xFF08;AWS &#x65E5;&#x672C;&#x8A9E;&#xFF09;</a><br /> あとは自分のざっくりとした理解</p> <ul> <li>導入には amazon のアカウント、AWS 用のアカウント、決済としてクレカかそれに準ずるなにか、あとは本人確認のために電話番号が必要 <ul> <li>企業でやるならメルアドはそりゃそうだけど、決済のクレカあたりまわりは少し気をつけたほうが利用料金の請求時にどうとかあるらしい</li> </ul></li> <li>EC2 が基本と考えていい。EBS はES2 のためのハードディスクのようなもので、S3 はあくまでそれとは独立したストレージ。RDS は DB だけど、細かい設定をしなかったりある程度手軽にパラメータなどを管理画面から行えるというあたりが楽らしい。</li> <li>public <a class="keyword" href="http://d.hatena.ne.jp/keyword/DNS">DNS</a> が AWS 環境下での接続するための名前(というか <a class="keyword" href="http://d.hatena.ne.jp/keyword/DNS">DNS</a>)。だけど、IP や <a class="keyword" href="http://d.hatena.ne.jp/keyword/DNS">DNS</a> は変わるようなので静的な IP をつけることができる。それが EIP。</li> <li>EC2 において STOP は EC2 の料金がかからないけれど、EBS を保持する料金はかかる。terminate は AMI ごと終了する。警告もでる。</li> <li>AMI は AWS で使うイメージファイルのようなもの。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%B7%A5%E7%A5%F3">ディストリビューション</a>ごとにセットで配布されてたりもするし、自分で設定した AMI を保存してそれを適合することもできる</li> </ul> </div> <div class="section"> <h3>かるくためした</h3> <p>さわっただけ。だいたいは資料と触った感じでわかったけど、以下の記事が導入としてわかりやすかった。いろいろ忘れてた。<br /> <a href="http://d.hatena.ne.jp/torazuka/20110420/ssh">&#x65B0;&#x898F;&#x306B;&#x4F5C;&#x6210;&#x3057;&#x305F;&#x9375;&#x3067;EC2&#x30A4;&#x30F3;&#x30B9;&#x30BF;&#x30F3;&#x30B9;&#x306B;SSH&#x63A5;&#x7D9A;&#x3059;&#x308B; - &#x864E;&#x585A;</a></p> <ul> <li>リージョンは Tokyo にした。なんとなく。EC2 は micro の一番小さいやつ。AMI は Amazon <a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a> AMI(64bit) を使用</li> <li>秘密鍵はリージョン単位らしい</li> <li>初期設定でのユーザーは ec2-user なので、そこから作業を開始しないといけない。root ではない。でもsudo 権限はついているので sudo su できる(なんか<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a> っぽい) <ul> <li>具体的には <a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a> ec2-user@ec2-xx-xxx-xxx-xx.ap-northeast-1.compute.amazonaws.com -i hoge.pem という感じ。</li> </ul></li> <li>EIP については適当に作成してくれるアドレスを associate Address で EC2 <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>に紐づけてやればいい。release で開放。その IP 自体を消すのはなんかそれっぽいものがある。</li> </ul><p>あとは普通に物理マシン、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BE%C1%DB%A5%DE%A5%B7%A5%F3">仮想マシン</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%BF%A5%EB%A5%B5%A1%BC%A5%D0">レンタルサーバ</a>ーでも<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPN">VPN</a>でも同じように <a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a> の鍵を配置してつなぐだけ。管理画面からも公開鍵の管理ができて、キーペアの作成もできるっぽい。コンソールに接続するのもブラウザに <a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a> のプラグインがはいっていれば使えるっぽい(さくらの<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPN">VPN</a>でもそうだった)</p><p>S3 に関してはとりあえずファイルを置く、消す、WWW に公開するというところまでやった。触るだけなら特に難しいことはない。</p> </div> <div class="section"> <h3>まあ</h3> <p>触るのは簡単。あとは適切に使えるか。適切にスケールアウトさせたり止めたりとか。</p> <div class="section"> <h4>蛇足</h4> <p>AWS を本格的に業務で使うときにどの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>をどのくらいどんな構成でどんな AMI でやるほうがいいのかはわからない。でも、AWS を触るだけなら簡単だったというのは、今まで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BC%AB%C2%F0%A5%B5%A1%BC%A5%D0">自宅サーバ</a>ーしてたりさくらの<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPN">VPN</a>を使っていたということ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a> を触る時に基礎的なユーザーの追加や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%DF%A5%C3%A5%B7%A5%E7%A5%F3">パーミッション</a>とオーナーの設定をとりあえず触れる程度に知っていたからだ。もうすこしいえば公開鍵認証というものがあって、公開鍵を ~/.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a>/authorized_keys に登録するという手順まで知っていたからだ<a href="#f1" name="fn1" title="まあここの名前はたしか sshd の設定で変えられたはずだけど、慣習的には変えないと思う">*1</a>。</p><p>差分を吸収するとはそういうことで、それすらわからない状況がプログラミングや仕事において大量にある。そういうことを少しずつメモしてあるのを公開したい。そして <a class="keyword" href="http://d.hatena.ne.jp/keyword/Sphinx">Sphinx</a> あたりにドキュメントとしてまとめて公開したい。かつての自分のために。プログラミングやエンジニアの「これくらいできて当然だよね」という水準は際限なく上がる<a href="#f2" name="fn2" title="まあ別にプログラミング/エンジニアだけじゃなくて音楽やイラストの界隈でもあるけど">*2</a>。なまじそういう界隈をみているというのもある。でも、彼らの「当然」の話は、おれには全然当然じゃなかったことはものすごくたくさんある。</p><p>それを本家にパッチを送ったりパッケージを公開する人もいるだろう。<a class="keyword" href="http://d.hatena.ne.jp/keyword/YAPC">YAPC</a> や PyCon みたいな運営、あるいは勉強会をする人もいるだろう。ほんとうにすごいとおもう。自分は勉強会とかオフ会経由でこの業界にはいった。その恩恵は受けている。でも、そうじゃなくて、おれはあくまでインターネットに、 WWW に公開された場所に、そういうなにかをおいておきたい気持ちがある。このブログは基本的にただの備忘録だけど、そういう側面はわりとある。</p><p>まあ、やるかはわからない。明日には忘れてるかもしれない。</p> </div> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">まあここの名前はたしか sshd の設定で変えられたはずだけど、慣習的には変えないと思う</span></p> <p class="footnote"><a href="#fn2" name="f2" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">まあ別にプログラミング/エンジニアだけじゃなくて音楽やイラストの界隈でもあるけど</span></p> </div> atasatamatara シェルスクリプトについてすこし学んだ hatenablog://entry/6435922169449606803 2013-03-12T19:03:54+09:00 2013-03-12T19:03:54+09:00 「今年はインフラやデプロイやシェルスクリプトはできなくていい」とはいったものの、ある人のスクリプトがたしかに便利でいい感じだった。ので、ちょっと触発されて少しだけかいて学んだ。以下、簡単なメモ。[改訂新版] シェルスクリプト基本リファレンス ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)作者: 山森丈範出版社/メーカー: 技術評論社発売日: 2011/04/27メディア: 単行本(ソフトカバー)購入: 8人 クリック: 113回この商品を含むブログ (11件) を見る 最速文法的な まあググるといいけど。以下、コメントにかく # 宣言時はなにもつけない a='… <p>「今年はインフラやデプロイや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%A7%A5%EB%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">シェルスクリプト</a>はできなくていい」とはいったものの、ある人のスクリプトがたしかに便利でいい感じだった。ので、ちょっと触発されて少しだけかいて学んだ。以下、簡単なメモ。</p><p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774146439/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/41GMyWgQ3cL._SL160_.jpg" class="hatena-asin-detail-image" alt="[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)" title="[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4774146439/hatena-blog-22/">[改訂新版] シェルスクリプト基本リファレンス  ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> 山森丈範</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2011/04/27</li><li><span class="hatena-asin-detail-label">メディア:</span> 単行本(ソフトカバー)</li><li><span class="hatena-asin-detail-label">購入</span>: 8人 <span class="hatena-asin-detail-label">クリック</span>: 113回</li><li><a href="http://d.hatena.ne.jp/asin/4774146439/hatena-blog-22" target="_blank">この商品を含むブログ (11件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p><p></p> <div class="section"> <h3>最速文法的な</h3> <p>まあ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%B0%A4%EB">ググる</a>といいけど。以下、コメントにかく</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># 宣言時はなにもつけない</span> <span class="synIdentifier">a</span>=<span class="synStatement">'</span><span class="synConstant">hoge</span><span class="synStatement">'</span> <span class="synComment"># 使用するときは $a と $ をつける</span> <span class="synComment"># 変数を展開するときはダブルクォーテーション</span> <span class="synStatement">echo</span><span class="synConstant"> </span><span class="synStatement">&quot;</span><span class="synPreProc">$a</span><span class="synStatement">&quot;</span> <span class="synComment"># 変数を展開しないときはシングルクォート</span> <span class="synStatement">echo</span><span class="synConstant"> </span><span class="synStatement">'</span><span class="synConstant">$a</span><span class="synStatement">'</span> </pre><p>ここまではまあいいとして、if の [ の実態や () や $ のつかわれかたがまちまちでかなり混乱してた。メモ。</p> <pre class="code lang-sh" data-lang="sh" data-unlink><span class="synComment"># if のあとの [ ] の実態は test コマンド</span> <span class="synComment"># test のエイリアスが [</span> <span class="synComment"># [ コマンドの最終引数が ] だと test コマンドの終了を意味する</span> <span class="synStatement">if [</span> <span class="synStatement">-f</span> ~/path/to/file <span class="synStatement">];</span> <span class="synStatement">then</span> <span class="synStatement">echo</span><span class="synConstant"> </span><span class="synStatement">'</span><span class="synConstant">hoge</span><span class="synStatement">'</span> <span class="synStatement">fi</span> <span class="synComment"># なので以下と同等</span> <span class="synStatement">if [</span> <span class="synStatement">-f</span> ~/path/to/file <span class="synStatement">]</span> <span class="synStatement">then</span> <span class="synStatement">echo</span><span class="synConstant"> </span><span class="synStatement">'</span><span class="synConstant">hoge</span><span class="synStatement">'</span> <span class="synStatement">fi</span> <span class="synComment"># [[ ... ]] も test コマンドとして似たような挙動をするけど、判定や終了コードの扱いが若干違う</span> <span class="synComment"># {} は関数定義などのブロック</span> <span class="synComment"># 関数定義</span> <span class="synIdentifier">func (){</span>...<span class="synIdentifier">}</span> <span class="synComment"># (()) は算術式。そのなかで定義された変数はローカル変数として扱える</span> <span class="synComment"># () はサブシェル。コマンドをまとめるときにつかう</span> <span class="synComment"># 関数定義の () とは違う</span> <span class="synComment"># 絶対パスを求める。 dirname $0 は相対パスになってしまうため</span> <span class="synIdentifier">BASE_DIR</span>=<span class="synPreProc">$(</span><span class="synStatement">cd</span><span class="synSpecial"> $</span><span class="synStatement">(</span><span class="synSpecial">dirname </span><span class="synPreProc">$0</span><span class="synStatement">);</span><span class="synSpecial"> </span><span class="synStatement">pwd</span><span class="synPreProc">)</span> <span class="synComment"># 関数定義で引数を使うときは $@ で可変長引数、 $1, $2 などで参照する</span> <span class="synComment"># ${hoge:~/path/to/file}ってのはなんかこうラベルを貼った参照?あまりよくわからない</span> </pre><p>[[]] について <a href="http://shellscript.sunone.me/if_and_test.html#if-2-9">if &#x6587;&#x3068; test &#x30B3;&#x30DE;&#x30F3;&#x30C9; - UNIX &amp; Linux &#x30B3;&#x30DE;&#x30F3;&#x30C9;&#x30FB;&#x30B7;&#x30A7;&#x30EB;&#x30B9;&#x30AF;&#x30EA;&#x30D7;&#x30C8; &#x30EA;&#x30D5;&#x30A1;&#x30EC;&#x30F3;&#x30B9;</a></p> </div> <div class="section"> <h3>まあ</h3> <p>あんまりまだちゃんとできなくていいけど、ちょっとしたときに使える武器はほしい。実際簡単なスクリプトをつくったけど、なかなか便利だった。</p> </div> atasatamatara パーフェクトPythonを読んだ hatenablog://entry/13425511277527238996 2013-03-11T20:28:17+09:00 2013-03-11T20:28:17+09:00 パーフェクトPython (PERFECT SERIES 5)作者: Pythonサポーターズ出版社/メーカー: 技術評論社発売日: 2013/03/05メディア: 大型本購入: 1人 クリック: 47回この商品を含むブログ (2件) を見る 1冊で言語仕様から最新の技術までを網羅した内容。網羅的に解説されているだけでなく、各技術に関しては基本からしっかり解説し、必要な箇所では、技術の進歩によってブラックボックス化が進んだ、内部処理が裏で何をしているのかを掘り下げて解説してあるため、体系的に知りたい初心者はもちろん中級者にもお勧めの一冊です.最新のPython3.3に対応 Python 3系を… <p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477415539X/hatena-blog-22/"><img src="http://ecx.images-amazon.com/images/I/51VfUS3xyrL._SL160_.jpg" class="hatena-asin-detail-image" alt="パーフェクトPython (PERFECT SERIES 5)" title="パーフェクトPython (PERFECT SERIES 5)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477415539X/hatena-blog-22/">パーフェクトPython (PERFECT SERIES 5)</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>サポーターズ</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%BB%BD%D1%C9%BE%CF%C0%BC%D2">技術評論社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2013/03/05</li><li><span class="hatena-asin-detail-label">メディア:</span> 大型本</li><li><span class="hatena-asin-detail-label">購入</span>: 1人 <span class="hatena-asin-detail-label">クリック</span>: 47回</li><li><a href="http://d.hatena.ne.jp/asin/477415539X/hatena-blog-22" target="_blank">この商品を含むブログ (2件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p> <blockquote> <p>1冊で言語仕様から最新の技術までを網羅した内容。網羅的に解説されているだけでなく、各技術に関しては基本からしっかり解説し、必要な箇所では、技術の進歩によってブラックボックス化が進んだ、内部処理が裏で何をしているのかを掘り下げて解説してあるため、体系的に知りたい初心者はもちろん中級者にもお勧めの一冊です.最新のPython3.3に対応</p> </blockquote> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> 3系を意識しているとか、言語仕様や周辺ライブラリの紹介ってのもあるけど、なにより Pythonic な文化であるとか習慣であるとか、それこそ「Zen of <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>」が日本語でここまで語られていることが貴重な書籍だと感じた。</p><p>以下は細々としたメモ。書き起こしてみたらだいぶ頭が弱い感じがする文章になってるけど、まあ、はい。</p> <div class="section"> <h3>with と context manager について</h3> <p>with open() as f っていうのはもはやイディオムになってるんだけど、たとえば fabric での cd コマンドでも context manager を使ってたりする。内部的には __open__ __exit__ などを呼ぶことで状態を管理できるというのはなんとなく調べたときに知ってたけど、少し整理がついた。</p> </div> <div class="section"> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/mro">mro</a> と superclass</h3> <p>これはどの言語でもある話だろうけど、最近 Django の class base view が mixin しまくっててよくわからなかったので調べていた。そのときに「誰が親クラスなのか」「その関数は誰のものなのか」というのを探すとき、<a class="keyword" href="http://d.hatena.ne.jp/keyword/mro">mro</a> が役に立つ。</p> </div> <div class="section"> <h3>文字列とバイト列</h3> <p>たぶん <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> を触るといやでも出くわすのがこれで、文字列だとおもったらバイト列で <a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-8">UTF-8</a> になってなくて UnicodeDecodeError とかはよくある。最近だと mesasge pack の話があったけど、マルチバイトなことを意識されてないコードとかわりとある。まあ実際 ascii(というか laten-1 ?) な文字列を扱う分にはたしかに不自由がない。文字の扱いについてやりだすとだいぶ面倒なので<a href="#f1" name="fn1" title="UTF-16やUTF-7であるとか、ではEUC-JPであるとかの違いがあることを知ってても、じゃあ Python 的に内部的にどこまでやってるかを知るのはいまはだるい">*1</a>避けてたところあるけど、すこし整理がついた。</p> </div> <div class="section"> <h3>C拡張</h3> <p>たとえば PIL あたりとか cPickle とかだと C の拡張を使うことになるというのはいいけど、それが具体的にどうやってるのかを知れて「へー」と思った。</p> </div> <div class="section"> <h3>nonlocal とクロージャ</h3> <p>JS だとよくあるクロージャを <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> でやるとき、nonlocal で一番近い変数を探しにいくところでつかえるというのはちょっとおもしろかった。ただ、それが <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> としてどう使えるのかはよくわからないけれど。</p> </div> <div class="section"> <h3>proprety アクセス</h3> <p>@property や @property.setter みたいな話。前 <a href="http://atasatamatara.hatenablog.jp/entry/20120907/1347024879">Python/Django &#x306E; property &#x3092;&#x3069;&#x3046;&#x6271;&#x3048;&#x3070;&#x3044;&#x3044;&#x304B;&#x30E2;&#x30D2;&#x30AB;&#x30F3;&#x3055;&#x3093;&#x306B;&#x76F8;&#x8AC7;&#x3057;&#x305F;&#x8A71; - AtAsAtAmAtArA</a> というのをかいたとき「とりあえず関数に倒しておくのが無難。でも状態が変わってないのならプロパティと明示してもいいんじゃないの」とあった。たぶん <a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a> においてのプロパティって話と、そもそも C みたいにプロパティアクセスがないという考え方を知らなかったので<a href="#f2" name="fn2" title="そこらへんは C を軽くさわったときや Obj-C についてすこしかじったとき少し脳内で整理がついた">*2</a>これもすこし整理がついた。</p> </div> <div class="section"> <h3>以上</h3> <p>たぶん最速文法的なところだったらウェブのチュートリアルをやればいいと思う。本当に公式のチュートリアルは充実していて、あれでだいたい使えるようになるとは思う。でもそうじゃなくて、これから <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> を本格的につかいたい、より <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> らしいコードをかきたい人にいいと感じた。個人的には文化や慣習、Zen of <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> なところをこうした形で伝えてくれるのはわりとうれしい。自分の場合たまたま <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> な会社でそういう環境だったからある程度知れたけど、きっとそういう環境であるところは少ない<a href="#f3" name="fn3" title="とはいえ、自分もPEP8には完全には従ってなかったりはする。具体的には80文字折り返し。PyPiになにかをあげたこともないし">*3</a>。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-16">UTF-16</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/UTF-7">UTF-7</a>であるとか、では<a class="keyword" href="http://d.hatena.ne.jp/keyword/EUC">EUC</a>-JPであるとかの違いがあることを知ってても、じゃあ <a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a> 的に内部的にどこまでやってるかを知るのはいまはだるい</span></p> <p class="footnote"><a href="#fn2" name="f2" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">そこらへんは C を軽くさわったときや Obj-C についてすこしかじったとき少し脳内で整理がついた</span></p> <p class="footnote"><a href="#fn3" name="f3" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">とはいえ、自分もPEP8には完全には従ってなかったりはする。具体的には80文字折り返し。<a class="keyword" href="http://d.hatena.ne.jp/keyword/PyPi">PyPi</a>になにかをあげたこともないし</span></p> </div> atasatamatara