未分類 – susumuis Info https://susumuishigami.github.io/susumuisinfo Webエンジニア susumuis の技術ブログ Tue, 04 Dec 2018 02:59:20 +0000 ja hourly 1 https://wordpress.org/?v=6.4.3 ビープラウドに入社して2年間で一番学んだこと https://susumuishigami.github.io/susumuisinfo/entry/2018/beproud Mon, 03 Dec 2018 13:43:59 +0000 http://www.susumuis.info/?p=1984 この記事は BeProud Advent Calendar 2018 の3日目です。

さて、何書くか考えてなかったまま担当の日を迎えてしまいました。そう言えばちょうど2年前の昨日ビープラウドに入社してから、技術者として転職エントリ書いてなかったと思うので今更書こうと思います。(非技術者向けの転職エントリは書いています

何で転職したんだっけ?

前職ではメイドが原因で失脚しました。というのは半分面白くするための冗談です。今から7年前、前職は小さな会社でしたが「これから大きくなるぞ!」という勢いがありました。その時技術リーダーだった僕は発言権もそこそこあり「良い技術チームを作りたい」という意欲に燃えていました。しかし結果的によくある保守的な階層組織になってしまい、気づいたら発言権も失い、大変憂鬱な気持ちになっていました。

「当初色々意見を言えたのに、思ったのと違う結果になったのはなぜだろう。」「いっそ自分が作りたかった雰囲気に近いチームに、自らが飛び込んでみたら分かるのではないか?」「じゃあ、それに一番近いのはどこだろう?」そこで注目したのがビープラウドでした。実は、7年前の僕が参考にウォッチしていたいくつかの会社の一つだったんです。

幸い採用ページを見るとこう思いました。

Python以外のスキルセットはぴったりカバーしているじゃん!!

Pythonが書きたくてビープラウドに入ったわけじゃなくてごめんなさい!ガチガチのJava屋さんだったので入社するまでPythonは全然書いたことがなかったです。Pythonは勉強しました。PyQっていうサービスで! Dog feeding!?

ビープラウドに2年いて学んだこと

流石に2年もいたんだから何か掴めたはずです!入社以来僕を変えたことを、大きかった順に書いてみようと思います。

1. 時間を大切にする

「susumuisは話が長い、文章が長い」とはめっちゃ言われました。

入社して最初の自己紹介では1時間以上話し続け、その後も社内勉強会で20分の枠に40分話すなど時間配分がとにかく苦手でした。また、文章を書くと「susumuisの文章は長くて読みづらい」とめっちゃ言われました。

人の時間は貴重です。説明が長ければそれだけ相手の時間を奪ってしまいます。相手の時間を尊重する、自分の時間も大切にするという感覚が欠如してたんですね。

2. わかりやすく伝える努力をする

「もっと分かりやすい図を書いて」みたいな指導をけっこうされました。

「仕様書は行間読め」僕はそんな文化で感じの人でした。汲める人が偉い人そう思っていました。ところが、この会社の人たちめっちゃ丁寧に設計するし、図で説明するのが上手い人が多いです。

考えてみると、業務の大半って、人から人へ自分の考えを伝えることなんですね。そこを「汲んで」とかやると、意思伝達のミスが多発して、最後はおかしなことになるのだと思います。

3. 根拠を示す

入社してから公式ドキュメントを読むことが増えました。社内ではレビューが盛んに行われます。そこでは、その技術判断をした根拠が必要です。まさか「よくわからないけどQiita読んで適当にやってたらできましたー(・_・)ノ」じゃダメですよねw

意見を言う時に根拠がないと、こう言うしかありません。

「俺が正しい。俺を信じろ!」

それで付いてくる人は少なくともエンジニアじゃなさそうです。。。

なぜsusumuisは熱い想いを実現できなかったのか!

自分がダメだったのは、この逆だったからです/(^o^)\

頭の中にあった「熱い想い」が、実はちっとも伝わってなかったんですね!それは失脚するわけです!

まとめ

susumuisがビープラウドに入社して2年を振り返りました。

  1. 「良い技術チームを作りたい」という熱い思いが実現できなかった悔しさを持って転職した
  2. その結果学んだのは次のことだった
    1. 時間を大切に。説明は簡潔に。
    2. 相手に伝わりやすく伝える努力をする
    3. 根拠を示して説明する
  3. たとえ熱い想いがあっても伝える努力をしなければちっとも伝わらない

もっと技術的な記事になるかと思ったけど、意外な結果だったなと思います。もちろん技術も学びました。Pythonは不安なく書けるようになったし、機械学習も学びました。でも技術は前提として、致命的な問題によってそれが活かせてなかったのかもしれません。

BeProudコミュニケーションガイド

現在社内でライフスタイル・コミュニケーションを作成中です。まだ策定中のβ版ですが、リポジトリは公開されています: beproud-guide 。読んでみると結構この記事で書いたことと近いことが書かれていると思います。

 

]]>
eclipseでHTMLエディタの文字化けを直す方法 https://susumuishigami.github.io/susumuisinfo/entry/2018/eclipse_html_charset Mon, 23 Jul 2018 03:14:09 +0000 http://www.susumuis.info/?p=1965 EclipseのHTMLエディタはcontent-type記述から文字コードを自動判別するが、DjangoテンプレートのようにHTMLの断片だけのファイルを開くと判別できず文字化けしてしまう。

回避するにはファイル個別に文字コードを指定すること。フォルダやプロジェクト、ContentTypeのデフォルトの文字コードを指定しても、自動判別をしてしまって強制的にShift_JISとして読み込んでしまう。これを直したい。

直す方法

Macの場合


$ cd /Applications/Eclipse.app/Contents/Eclipse/plugins
$ jar -xvf org.eclipse.wst.html.core_1.3.0.v201804302243.jar plugin.xml plugin.xml
$ vim plugin.xml 

次の部分 note: no default-charset for HTML, should use 'platform' の下のdescriberをコメントアウトする


<!-- note: no default-charset for HTML, should use 'platform'
<describer class="org.eclipse.wst.html.core.internal.contenttype.ContentDescriberForHTML" />
 -->

$ jar -uf org.eclipse.wst.html.core_1.3.0.v201804302243.jar plugin.xml plugin.xml 

これでプロジェクトや親フォルダの文字コードを優先して従うようになった。

考察

この動作、Java使いだった頃は全然気にならなかったのに、Python/Django使いになったら真っ先に気になった。

Mayaaテンプレートはブラウザで表示できる「ページ」だから、むしろ自動判別が正しい(忘れてたり指定が間違ったら「正しく化けて欲しい」)。
JSPの場合もpageEncodingディレクティブがある。忘れたらサーバーサイドで化ける。

Djangoテンプレートはいずれの記述もない。この辺りも文化の違いなのかな。

]]>
PyPro3は機械学習の仕事に初めて関わるプログラマーにもおすすめの本です https://susumuishigami.github.io/susumuisinfo/entry/2018/pypro3 Sat, 23 Jun 2018 06:21:12 +0000 http://www.susumuis.info/?p=1946  

ビッグデータの活用が進み、機械学習をシステムに組み込む事例が増えています。これまで Webや業務システムを開発していたプログラマーも、今後「機械学習プロジェクト」に参加することが増えていくでしょう。

しかし、初めての分野の仕事は緊張しますし、コツが分かっていないと失敗することがあり、不安になってしまう方も多いのではないでしょうか。そのような方のために、6月12日に発売したPythonプロフェッショナルプログラミング 第3版」(株式会社ビープラウド著)では、第15章プログラマーのための機械学習」の執筆を担当し、自分が仕事を通じて理解したノウハウや仕事をする上での心がけを書きました。

本の概要

この本はハイレベルなPythonエンジニアが集うビープラウド社が日々の業務で培った開発手法をまとめた本で、ビープラウドのメンバーが分担して執筆しています。この一冊で開発環境の構築、開発チームコミュニケーション、テストやCI、パフォーマンス改善、Djangoから機械学習まで幅広く網羅しています。詳しくはharu, shimizukawamtb_betaが書いている記事を御覧ください。

すでに多くの方がお買い上げいただいているようで、一時、Amazonの開発技法カテゴリで売れ筋1位だったそうです。ここでは、既にお買い上げ頂いた方でこれから15章を読む人に向けて、まだお買い上げいただいていない方に15章という切り口での宣伝を少し書かせていただきます。

15章は誰に読んでほしいか

冒頭に書いたとおり、これから機械学習を仕事として経験するプログラマーを主なターゲットとしていますが、次のような幅広いにも読んで頂けるのではないかと思います。

  • プログラマーを管理するプロジェクトマネージャー
  • システム開発会社の経営者
  • 機械学習を扱うコンサル

Pythonプロフェッショナルプログラミング全体の読者層を想定しているため、プログラミングの知識は前提として書いていますが、数式など機械学習やデータサイエンスの専門知識は一切不要です。

15章執筆者の狙い

「教師あり、教師なし、強化学習に分かれ、教師あり学習は分類、回帰がある」といったよくある説明は一切カットしました。それらを説明している本はたくさんあるからです。今、専門知識を教えてくれる本はたくさん出ています。自分も読書会を通じて勉強する場を作っています。

一方、プログラマー視点での「仕事の進め方」の本は現時点ではありません。

本職のプログラマーのみなさんが仕事を始めた時、専門知識以外に何を覚えたでしょうか?要件定義、設計、開発、テスト、納品」という仕事の流れとスケジューリングの大切さではないでしょうか?仕事の流れがわかっていれば、優先順位やスケジュール感を身につけることができます。それが分かれば適切なタイミングでマネージャーに相談することもできます。

しかし、機械学習の仕事では、ウォーターフォールのような開発モデルをうまく適用できません。そこで、従来のシステム開発の知識がある人に何を補ったら効率よく仕事で活躍できるのか?そのことに注力して執筆しています。

15章に書いたこと書かなかったこと

よって、この章を読んだ人が得られると思うことは次のことです

  • 「機械学習」のざっくりした概念
  • 機械学習を含んだプロジェクトの全体像とスケジュール感
  • 仕事をする上での心がけや作業の優先順位

一方、次のことは書いていません

  • 機械学習の専門知識
  • 機械学習アルゴリズムの説明
  • 数学的な理論

これらを補うため、章末に参考書籍が書いてあります。これは筆者も実際に読んで学んだ本なので、順に読めば既に僕と同じレベルに達するとご理解ください。なお、今後僕の主催の読書会でもこれらの本を扱っていくかもしれません。


15章の冒頭

15章の構成と担当チーム

15章は次のように4部構成になっています。

  1. 機械学習とは
  2. 機械学習プロジェクトの概要
  3. 事前検証フェーズ
  4. 機械学習の開発環境を準備する

自分はこの中でも1〜3節を執筆しました。しかし実際は1、2節は非常に短いので、実質1〜3節で1セットだとご理解ください。

4節は同僚で、同じく機械学習案件を多数経験し、専門知識やライブラリの使い方の知識が豊富な先輩であるmasayaが執筆しています。masayaと僕は同じプロジェクトのチームになったことがあり、僕が外部調整や個々の処理の糊付け的な開発を担当し、内部のエンジンをmasayaが作りきるという役割分担をして大きな機械学習システムを完成させた仲です。今回も同じチームで1つの章を担当できたことを嬉しく思います。

章末コラム「機械学習で知っておきたいプログラミングテクニック」は2人の合作です!実際の仕事を通じて切実に感じたことを厳選して書いています。

はじめての執筆の感想

2017年9月末に執筆を開始、3月に脱稿、その後度々レビューを直しを経て5月にようやく最終稿を出すことができました。

脱稿まで一体どんな文章を僕が書いていたのか、多くの方にはご心配をおかけしたと思います。僕自身何度もほぼ一から書き直し、構成にドラスティックな変更を加え、一日中日本語のリファクタリングに追われる日々でした。

脱稿後のレビュー直しも大変で、最後は自分一人で文章を書くことができなくなり、意見をくれた数人を招集し、修正方針を練る会議を行っていました。

初めての執筆だったので、執筆チーム、レビュアーチームの皆さんには大変ご迷惑をおかけしました。特に全体のマネージメントを行う傍ら苦しむ僕の道筋を示し続けてくれたtakanory、同じ章担当で積極的に意見をくれたmasaya、レビューで厳しい指摘と温かいアドバイスをくれたharu, shimizukawa, kashew_nuts, mtb_beta, tsutomu, nakagami、説明を分かりやすくするために協力してくれたnatsu, nao_yに感謝します。


見本を手に取りはしゃいで自撮りする僕

まとめ

以上、Pythonプロフェッショナルプログラミング 第3版は「機械学習」の本としても他の本では得られない、個性的な位置づけの内容を含んでいるますので、是非読んでいただければと思います。

まだ、ご購入いただいていない方は、全国の書店またはAmazonなどで購入できます。電子書籍版もあります。

]]>
エンジニアが機械学習を仕事とする周辺環境 https://susumuishigami.github.io/susumuisinfo/2017/engineer_machinelearning_work Mon, 09 Oct 2017 02:37:05 +0000 http://www.susumuis.info/?p=1860 メイドカフェでノマド会 座談会開催しました!

を開催しました。

資料はこちらです。

僕はエンジニア視点で話しましたが、コンサルの方の参加もあって、話が広がりました。ここ数ヶ月もやっと思っていたことが議論をすることで腑に落ちた感じがします。若い学生の方の意見も聞くことができたこともよかったと思います。

議論の内容は結論はスライドに書いているとおりですので、そちらをご覧ください。

今後もこのようなプチイベントの開催を増やしていこうと思います。「参加したい!」「こんな企画をやりたい!」と思われた方はまずは、ノマド会の公式サイト にアクセスし、Slack, connpassに登録いただき、 Slack 上で声をかけていただければと思います。

]]>
「Swift」という名のバンドを見つけたから、エンジニア代表として話を聞いてきた https://susumuishigami.github.io/susumuisinfo/entry/2017/swift_band_interview https://susumuishigami.github.io/susumuisinfo/entry/2017/swift_band_interview#respond Thu, 12 Jan 2017 07:07:51 +0000 http://www.susumuis.info/?p=1785 皆さん、Swift書いてますか?

今やObjective-Cじゃなくて、iOSアプリ開発はSwiftです!今年は「Android、もしやお前も!?」みたいな噂もあったりしました。既に多くの企業が注目していると言われる言語、もうエンジニアたるもの勉強しておかなければヤバイ雰囲気があります。

そんな中、今日はプログラム言語ではなく同じ「Swift」という名前で活動しているバンドを見つけたので紹介します。まあ、こじつけネタwwwと言わず、読んで欲しく思います。というのは、なんてGooglavility低いバンド名なんだ! さぞかし、SEOでは苦労しているだろうと、興味が湧いて、勢いでインタビューしてみたら、想像以上にイイ話が聞けてしまいました。

Swiftとは

Swift は、《会社》をコンセプトにして2015年4月から活動を開始したバンドグループで、リーダー兼ギタリストのホッタとヴォーカルの多田を中心に活動中。代表曲は「オレンジ」「手のひら」「BRAVER

リーダーのホッタくんと僕の仲

何を隠そう、僕とホッタくんは小学校の同級生で、今回のインタビューは久しぶりの再会でした。なので終始砕けた会話になっていることを、ご容赦ください。

もちろん、文章を校正して固い言葉に直すこともできたのですが、彼の人間性、思いを伝えるには、このままの方が良いと思います。

Swiftの名前は「響き」で選んだ

susumuis: 早速だけど、Swiftの名前の由来ってなに?

ホッタ: 由来?そうだなあ。「響き」かな。

susumuis: 響き?

ホッタ: 「優しい」「耳馴染みの良い」感じ。ほら、印象ってあるじゃん。強そうな人は強そうな名前だし、僕も一緒にやってるタダくん(「ハリー」って呼んでるんだけど)も、僕ら二人「優しい」イメージって言われるんだ。

susumuis: へえ

ホッタ: 第一印象で決めるのは良くないけど、人の性格って顔に出るよね。バンドにとっては、名前が一つの「顔」で「名刺」なんだよ!

susumuis: Appleの言語と名前がかぶったのはどう思うの?

ホッタ: 実はあっちの方が先で、知ってたんだよね。あと、音楽の世界では世界一稼いだ女性アーティスト「テイラー・スウィフト」もいるし、検索で勝てるわけがない!それでも「僕らに合ってるね」って選んだんだ

susumuis: 今検索してみたら、金融業界でも、SWIFTって組織があるよ!

就職しても音楽はできる!

ホッタ: Swiftのメンバーって実は全員就職しているんだ。仕事をやりながらでも、やりたいことを実現したいと思ってる。みんな仕事には責任があるから、それは守っていきたい。だから、仕事が最優先で活動してる。

susumuis: そうなんだ!

ホッタ: 「会社があるから」諦めてるやつ多いんじゃないかな?でも、「挑戦した?」「やろうとすればできるじゃん!」って証明したい。挑戦しないで口だけの人多いから。

susumuis: 僕らエンジニアの世界でもそういうのあるよ!「仕事が忙しい!」とか言って挑戦しない人。でも、やっている人はやっていて、気がついたら大きく差が開いちゃうんだよね。

ホッタ: でも、正直続けることの難しさはあるよ。「日本は音楽を続けるのは難しい」と言われるんだ。「バイトで生計立てて夢を目指す」人が多いんだけど、最終的に諦めるんだよね。「そろそろ就職しなきゃ」って言って。でも、「就職してもできるよ!って伝えたい。

「責任ある仕事をしている」というホッタの会社の名刺を見せてもらったら、とても立派な肩書がついていました!

《会社》をコンセプトにしたのは、人の大切さを伝えたいから

susumuis: コンセプトは「会社」ってことだよね。でも、正直言うと申し訳ないんだけど「会社」ってほら、ネガティブなイメージあって!「今日も残業だ。」とかへとへとになって、ライブに行ったら「また会社kayo。。。」みたいにならないの?

ホッタ: 会社ってそういうイメージもあるよねー。。。でも僕らにとっては「会社」=「ファミリー」なんだ。同じ目標を持って、志は同じでやりたいことをやる。そういう人たちが集まっていれば「辛いことがあっても、楽しい」と思えることが多いんじゃないかな!

「家族型経営」と呼ばれた会社の姿。それこそが真の会社のあり方なのかもしれません。リストラや経営合理化による非正規雇用の増加で「人が駒のように扱われている」今が異常なのかも。今こそ、「会社」をテーマにしたバンドをやる意味があるじゃないかと、聞いていて思っていました。

現実は厳しいけど、僕達は恵まれている!

ホッタ: そういうわけで、僕らは「仕事を大事にする」って事情だから、あまり多く活動ができないんだ。ライブも年に数回しかできない。普通のバンドは活動をしなければファンが減ってしまうから普通はライブを一杯やるんだ。別のバンドと共同でライブやったりしてね。そういうのを「タイバン」って言うんだけど。そして赤字でもライブをやる。僕らはそのやり方はどうなのかな?って思っているよ。

susumuis: それでもこの間のライブではライブハウスを満員にして大盛り上がりだったよね!あの時は何人いたの?

ホッタ: 100人くらいだよ!僕たちみたいに、バックボーンがない、事務所がついているわけでもない、そういうスタイルでは、この人数は多い方だと思う。僕達は恵まれているって思うよ!

「オレンジ」を卒業ソングとして広げたい

susumuis: 最初「オレンジ」や「手のひら」を聴いた時、「なんて優しい歌なんだろう」って思ったよ。あの曲はどういう思いが込められているの?

ホッタ: 「オレンジ」は「卒業」をテーマにしているんだけど、「卒業しても会えるでしょう?また違う仕事で繋がれるじゃん!その時は、当時と同じ距離感で接することができたら素敵だよね!」って思いが込められてるんだ。

susumuis: ITエンジニア代表として共感する!僕らは比較的流動性の激しい職業で「転職」ってありふれているんだ。お陰でしょっちゅう「卒業」してる。で、前に仕事したことがる人と、また一緒に仕事してたりするよ!だから、「卒業」のたびにこの人とまた仕事ができる日が来る!って思ってる。今の時代の「卒業」ってそうなのかもね。SNSの普及で普通に会えるし。

ホッタ: できれば卒業ソングとして定着させたいな。学校とかで、卒業式に合唱してくれたらいいな。

真面目にやっているから、ファンが離れない

susumuis: 偏見で申し訳ないけど「バンドマン」ってチャラいやつが多いってイメージあるじゃん。実際はどうなの?

ホッタ: 実際そういうの多いよ。僕らは先輩にも「お前らは本当に真面目だな」って言われるよ。だからなのかもしれないけど、一度ファンになったら離れる人が少ないように思う。

中学生の女の子が自分を「尊敬する人」と言ってくれた

ホッタ: 今までで一番うれしかったことで、中学生の女の子が学校の発表で自分を「尊敬する人」として紹介してくれたんだ。

susumuis: その子は元からの知り合い?

ホッタ: いや、元は相方のファンでライブに来てくれたんだけど、僕とは初対面。ネット番組とかで僕の思いとかを知ってくれて。

susumuis: それは嬉しいね!思うんだけど、バンドとか、アイドルとか表に出る人は若い人に影響を与えるから「ちゃらい」とかじゃなくてお手本としての責任も感じてるんじゃないかな。

ホッタ: そういう意味だと、TwitterとかSNSには気を遣っているよ!若い子が見ているから、自分がどう見られてるか。常にポジティブにして、ネガティブな言葉は書かないように気をつけてる。そこはオープンな場だから。仲間内だけのクローズドな場所じゃないからね。

今後は活動を加速していきたい!

susumuis: 今後の展望とかはあるんですか?

ホッタ: 活動を長く続けていきたいと思う。来年の4月で活動3年目なのでアクセルを踏んで活動をスピードアップしたいと思ってる。ライブ会場を大きくしたりね。それは大変になるかもしれないけど、沢山の人に知ってもらえたら良いなって。でも、いろんなことに手を出したら中途半端になるから、絞って行きたいとは思ってるよ。

susumuis: 期待してます!

今の時代は「人」が中心

ホッタくんの話を聞いていると、彼は思ったことを本当に率直に話してくれる人だなと思いました。そして根が明るいから、話してるこっちもだんだん楽しくなってきました。

彼らから学べることはこういうことなんじゃないかと思いますが、これは我々エンジニアにも大切なことだと思います。

  • 挑戦すること
  • 人を大切にすること
  • まじめにコツコツやること

これからも一層活躍されることをお祈りします。

ライブ情報

2月11日にワンマンライブがあります!

http://www.swift-inc.net/news

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1785 0
Javaが僕にくれたもの https://susumuishigami.github.io/susumuisinfo/entry/2016/java_advent https://susumuishigami.github.io/susumuisinfo/entry/2016/java_advent#respond Sat, 03 Dec 2016 07:57:48 +0000 http://www.susumuis.info/?p=1809 この記事はJava Advent Calendar 2016の3日目です。2日目はmegascusさんのどこからも使用されてないクラスを列挙する、4日目はcero_tさんです。

退職しました

個人的な話で恐縮ですが、去る11月末をもって学生バイト時代も含めて12年間勤めた会社を退職しました。そこではずっとJavaを書いていましたが、次の勤務先ではPythonを書くので、今後Javaを書くことは少なくなるでしょう。

退職エントリは書きませんが、代わりに言語の卒業エントリを書こうと思います。一人よがりなネタですがお許し下さい。

初めての出会いはJDK 1.1をダイアルアップでダウンロードしたこと

正確な時期は忘れましたが、1997-8年頃ではなかったかと思います。「Javaという言語がすごいらしい」という噂をきいて、ダイヤルアップ回線で頑張って一晩くらいかけてダウンロードしてみました。その時落としたのはJDK 1.1ではないかと思います。

しかし、当時使っていたPentium 90MHzのマシンではサンプルアプレットのローディングに数分かかり、クリックの応答に数十秒かかるという状況でした。(「Java遅い!」をリアルで体験した世代です)

初めてまともに使ったのは、i-appliの開発

時は流れて、2001年1月「NTTドコモの新機種F-503i, P-503iが、Javaに対応して誰でもアプリが作れるようになった!」というニュースが入ってきました。この時高校生だったのですが

「これはやばい!ケータイがPCになってしまう!」

とか言って、親に土下座して買ってもらいました。

Javaといっても、CLDC(Connected Limited Device Configuration) 1.0という仕様の上に作られたJavaであって、「浮動小数が使えない」などの制限があり、しかもアプリ(すなわちjarファイル一個)のサイズは10KB以下に収めなければなりません。そこではclassファイルを増やすと容量がかさむから「クラスは一個にしましょう」と言われていました。Eclipseはまだなくて、JBuilderは僕のPCでは重いから、[CPad for Java] (http://hp.vector.co.jp/authors/VA017148/pages/cpad.html) というテキストエディタにコンパイラショートカットがくっついたようなエディタで頑張ってコーディングしていました。これと、コードの変数名を1文字にして容量を削る今で言うminifyツールみたいなのも使っていました。

その時作った作品はgistに貼ってあります高校の先輩がVBで作ったゲームを移植したものです。当時は雑誌の端に載ったりしました。

大学に入ってJavaらしくないJavaを学ぶ

2003年に大学生になったのですが、当時入った学科では、プログラミング教育にJavaを使っているということで、楽しみにしていました。ところが、そこで習ったJavaと言うのは

「配列をReturnする『関数』を作ってはいけない」
「まず配列を作ってメモリを確保しろ、その配列を関数のパラメータに突っ込め!」

みたいなやつでした。。。\(^o^)/

本当のJavaを求めてある本に出会う

そんな時に出会った本がこれでした。

今思うと現場思考で、非常にバランスの良い本だったと思います。

これで、少しはクラスとかデザインパターンというものを知った僕が、少しはプロセッサーパワーがましになった当時の携帯向けに作り直したのが[これ] (https://github.com/susumuishigami/bunshi2) です。

最近このコードをほぼそのままコピペして環境に依存する部分だけ書き換えてみたら、あっさりAndroidで動いてしまいました!

仕事でサーバーサイドJavaの世界へ

大学2年生の時から、プログラミングのバイトを初めます。従業員10人くらいのこじんまりとした会社でした。

始めて突っ込まれた案件は、Atg Dynamoというフレームワークを使っていました。すごい重量級フレームワークでした。二度と使いたくありません。

自社開発の仕事にアサインされる

その案件が終わってからは、ほぼ一貫して自社開発の製品の新規開発・カスタマイズをやっていました。そこで使っていた自社フレームワークはシンプルで使いやすかったですが、データは全部文字列で扱う流儀で、HashMapみたいなデータ構造に

set(“LAST_NAME”, “hogehoge”);
set(“FIRST_NAME”, “hugahuga”);

みたいなコーディングスタイルでした。。。まさか、このフレームワークをその後10年使い続けるとは思わなかった\(^o^)/

システムのリニューアルを任され、自由に学べる期間があった

ベンチャー企業というのは、何が正しいかよりも目の前の問題を最短で解決するのが良いとされることがあるので、その場限りの仕事を数年続けました。

転機は2008年の暮れ、主力システムをリニューアルする任務を与えられ、自由にやっていいと言われました。そこで、当時のトレンドだったWicket、Seasar、Spring、Google Guiceなどを全力で追いかけてみました。

本当はこの時社内標準フレームワークを刷新したかったのですが、工数を考えると既存資産を活かすことがどうしても必要だったので、従来の自社フレームワークに僕がOSSから学んだエッセンスを加えるという方針にしました。そのため、「フレームワークの使い方」より、フレームワーク自体のソースコードを読むようになり、特に、Seasar2のソースコードは読みやすくて勉強になりました。(Apacheライセンスなので流用もしやすく助かりました!)

結局、テンプレートエンジンとしてMayaaだけ採用しましたが、たまたまその後作ったサービスが成長したため、最もMayaaを使い倒している人みたいになってしまいました。

エンジニアとしての目標: 30までに勉強会で登壇する

僕は家庭の事情もあって、2009年ごろまで、IT系勉強会というものに参加したことがありませんでしたが、このまま無名のエンジニアではいたくないと思い、「30歳までに勉強会で登壇する」ことを目標としていました。

結果的には、
2012年と、2013年のJJUG CCC当時、28, 29の時に実現できたので、目標は達成したことになります。

Season Conferenceは2010を最後にしばらく開催されませんでしたが、もし、2011年に開催されていたら、この、2013年のネタはその時できたと思います。

最後のSeasar Committerになる

そして、久しぶりに開催された2015年のSeasar Conferenceが開催されこんなLTをし、

その後、初めてMayaa初代メインコミッターの栗原さん、現メインコミッターの須賀さんに出会うことができ、そのまま流れで僕もコミッターにしていただきました。そしてどうなったかはこのスライドのとおりです。

コミッターになってからした仕事はMayaa Advent Calendar 2015を書いたことくらいです。コミットしてないです。(今後必要があったら、コミットすることもあるかもしれません。コミッターになる前はバグ報告をしてパッチを送ったり、GitHubになってからは、PullRequestを送ったことがあります)

振り返って、Javaと僕の付き合いは何だったのか

僕はJavaで12年仕事のコードを書いてきましたが、今の今まで、J2EE、Java EEのような世界は、Servlet/JSPくらいしか経験がありません。EJBも書いたことがありませんし、JPAも使わず生のJDBCに独自ラッパーをかぶせてなんとかしました。SpringやSeasarContainerも業務で使ったことはありません。

勉強して、こういうの良いなと思ったら、ポイントポイントでどんどん取り入れていきました。アプリケーション・サーバーは、Tomcatくらいしか使っていません。そのため、本来であればアプリケーションサーバーが提供してくれるような機能も自作しました。

こういうところは、このあたり、一般的なJavaプログラマーとは違うかもしれません。

それならいっそ、PHPを使えば良いんじゃないかと言えますが、静的型付け言語であるJavaのIDEの実力・Eclipseにはお世話になりました。サービス開発初期は何が正解なのか分からず、動かしながら抜本的に作り直すなんてこともあります。その時、呼び出し階層・型階層の機能がなければつらいかった。

ただ、中盤以降はIDEに頼り切るスタイルが仇となって、どんどん重たくなって苦しくなりました。

持論ですが、ある程度大規模になると、場当たり的な設計をやめ、モノリシックをやめ、きちんと設計して、適度にマイクロサービスみたいにモジュール分割するのが正解だと思います。そして、各マイクロサービスは、JavaよりもLLの方が書きやすいと思っています。

Javaプログラマーから見たPython

新天地ではPythonistaになります。まだ一ヶ月くらいしか触っていませんが、Pythonは非常にとっつきやすい言語だと思いました。同じことができるフレームワークやライブラリが乱立せず、体系的に整っているように見えます。

お陰で非常に入門しやすく、何かをするにあたって迷ったりはまったりすることが極端に少ない言語だと思いました。

Javaは僕の育ての親

しかしJavaはSeasar Project等、日本発のJavaのOSSという教材に恵まれているために、質の良いコードを読ませてもらって学習させてもらえたことはかけがえのない経験だったと思います。

初めて触ったプログラミング言語はObject Pascal(Delphi2.0)ですが、業務で実用的に使い、多くの先人の知恵を学ばせてもらった、僕の育ての親はJavaであることは間違いありません。

これからはEclipseを起動することも少なくなると思います。そのうちショートカットも忘れてしまうかもしれません。それでも、僕のプログラミング哲学に影響を与えたのは、Javaであり、とりわけ、Seasar Project関係のOSSのそれぞれの開発者の方々の知恵を借りてこれからも頑張っていきたいと思います。

番外編 java-ja について

僕にとって java-ja は発足当時から憧れのコミュニティでしたが、家庭の事情でイベントに参加することは今まで一回もできませんでした。この記事が公開される12/3には java-ja 忘年会があって、実は java-ja のイベント初参加です。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1809 0
Bash on Windowsを入れてみてやってみたこと https://susumuishigami.github.io/susumuisinfo/entry/2016/bash_on_windows https://susumuishigami.github.io/susumuisinfo/entry/2016/bash_on_windows#respond Fri, 19 Aug 2016 01:38:05 +0000 http://www.susumuis.info/?p=1776 出遅れてしまいましたが、8月頭に公開されたWindows 10 Anniversary Updateについて、書きます。

目当てはもちろんBash on (Ubuntu on) Windows

他にも色々変わっているようですが、僕はこのためにアップデートしたんだと言うくらい、この機能に期待していました。導入の仕方はこの辺りを参考にすると良いと思います。

http://qiita.com/Aruneko/items/c79810b0b015bebf30bb

僕が入れてみたもの

ssh

標準のターミナルがCommand Promptで、日本語とかがうまく表示されなかったりするので、とりあえず、これを入れて、PuttyとかPoderosaでアクセスしたい!こんなことせずにmsys2やcygwinみたいにminttyでアクセスできると良いんだけどね。

http://qiita.com/ubnt_intrepid/items/84a56a01cf7081401917

こちらの記事では、/etc/ssh/sshd_configに以下の表記が必要ということだったけど、PasswordAuthentication yesは不要で、ちゃんと鍵認証できました。

UsePrivilegeSeparation no
PasswordAuthentication yes

LAMP環境

まあ、王道的使い方の一つというか、Web開発するときに、マカーたちがローカルに環境をホイホイ立ててる間にWindowsっ子は(Windows版で環境を立てると微妙に違って動かないとか言われて)仮想マシンをセットアップしなければならなかったことがなくなるのは良いですね!

$ sudo apt-get install php5 php5-mysql mysql-server
$ php -S localhost:8000

これでローカル8000ポートでPHPが動くことを確認できました。

ただ、MySQL部分だけはWindows版を動かしたほうが早いかも!

PHP7

Bash on Windows のUbuntuは14.04 LTS準拠らしいです。ちょっと古いですよね!PHPも5が標準のようです。

次の記事を見ると、16.04にすることもできるみたいですが、あまりテストされていないだろうと考えると怖いので、あくまで14.04の範囲で頑張ろうと思います。

http://qiita.com/Aruneko/items/2670f42d36a7508c13bb

せっかくならPHP7を入れてみましょう。

$ sudo add-apt-repository ppa:ondrej/php
$ sudo ape-get install php7.0

まあ、普通に入りました。

node環境

これこそやりたいことですよね!今時npmをまともに使えないWindowsは取り残されてた感満載でした!

ただ、

$ apt-get install nodejs

で入るnodejsは古いので、使ってはいけないようです。。
最初これをやってしまってハマりました!

次の記事などを参考にして最新版のnodeをインストールすれば、npmなども最近の記事に書かれているとおりに動きました。

http://qiita.com/TsutomuNakamura/items/7a8362efefde6bc3c68b

$ sudo curl -sL https://deb.nodesource.com/setup | sudo bash -
$ sudo apt-get install nodejs

ただ、現時点でnodejs, npm界隈は流動性が激しく、ほんの半年前の記事に従って操作しても、書き方が変わっていたりして思ったように動かなかったりしました。

とはいえ、これはWindowsの問題じゃない

HHVM, mariadb

PHP7、mysql5.6が動けば別に構わないのですが、せっかくなので、HHVM, Maria DBの組み合わせも動くかどうかやってみました。

結論としては動きました(^o^;)

やり方は、僕の記事が良いのではないでしょうか?

http://www.susumuis.info/entry/2014/06/11/222935

この上で、WordPressなんかもすんなりと動いてしまいました!

せっかくなので、一時的にポートを開けて外部からアクセスしてみて速いかどうかテストしてみましたが、同じWindows上のHyper Vで動かしているHHVM + MariaDBなWordPressの方が速かったです!

SSH for WindowsからBash

今の状態では、Bash on Windowsはあくまで開発者用で、サーバー向けではありませんから、Bashウィンドウを開かないとSSHなどができません!

自宅サーバーのメンテナンスに、リモートデスクトップを使っていますが、スピードの遅いモバイル回線ではこれはきついので、SSHできたら便利です。

一応、SSH for Windowsというのはありますが、リモート越しにコマンドプロンプトになるので、あんまり嬉しくない。(Power Shellとか使いこなせると良いらしいですが。。。)

そこで、SSH for Windowsごしにbashとコマンドを打って、Bashに切り替えられたら便利だなーと思ってやってみたのですが、どうもこれはダメみたいです。

総評

他の方のブログを見させていただいたところによると、Docker動かそうとして動かない。Oracle JavaやOpen JDK動かそうとして動かないなど、色々と動かないものもあるようです。

しかし、とはいっても、 Ubuntuなのが良いです!Ubuntu向けのWebの記事のまんまやって大体動きます!HHVMは長いことMac用のバイナリがリリースされていなかったので、場合によってはかえってWindowsの方がネイティブ環境を立てやすいということになるかもしれません!

今時、Linuxを使うといっても、ソースからビルドして環境を建てられる猛者はあまりおらず、aptやyumなどのコマンドラインで解決するのがほとんどです。ああ、僕が欲しかったのはLinuxではなく、Ubuntu(またはDebian)だったのか〜と痛感しました。

ただ、ターミナルで日本語が欠けて表示されてしまうなど、不完全なところも多い部分は今後に期待です。

また、「開発者モード」にしないとインストールできないので、現場によっては、「開発者モード」への設定が禁止されて使うことができないかもしれません。あと、タブレットでよく使われている32bit版Windows版には提供されていないようです。

そう言った、もろもろのことを考えると、Windowsでcurlやgrepなどのコマンドラインが欲しいという用途では、msys2 が現状では最適のように思います。

しかし、なんといってもUbuntuということで、今後に期待したいと思います!

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1776 0
Javaでオブジェクトを使いこなすために知っておくべきこと – メイドさんでも分かるプログラミングシリーズ vol.2 https://susumuishigami.github.io/susumuisinfo/entry/2016/java_object_technic https://susumuishigami.github.io/susumuisinfo/entry/2016/java_object_technic#respond Sat, 02 Jan 2016 13:46:10 +0000 http://www.susumuis.info/?p=1709 前回に引き続き、メイドさんにプログラミングを教えるためのシリーズです。

前回「オブジェクトの多態性ができると便利です」と説明しました。今回は、なぜ便利なのか分かるように、プログラミングでよく使われるテクニックを6つ紹介したいと思います。

これらを知ることが出来ればオブジェクト指向のメリットを理解出来るだけでなく、実践でプログラミングをしているプログラマーと、かなりコアな会話ができるようになりますよ!

その1: 関数オブジェクト

プログラムをしていると「何か起きた時に、この関数を実行して欲しい」という時が良くあります。このような、ある条件の時に実行してもらう関数のことを「コールバック関数」と呼びます。

Javaはメソッドを変数や関数のパラメータに代入することができませんので、こういう時、コールバックして欲しい処理を書いたメソッドを持つオブジェクトを作って、それを渡します。

このようなオブジェクトのことを関数オブジェクトと呼びます。

例えば、架空のクラスですが、WebClientというWebサーバーに通信をして、通信が成功した時に行う処理を指定できるようになっているとします。WebClientResponseCallBackというインターフェース

webClient.connect(new WebClientResponseCallBack() {
    @Override
    public void onSucceeded(int status, String result) {
        System.out.println("成功しました");
        System.out.println(status);
        System.out.println(result);
    }
    @Override
    public void onFailed(String result) {
        System.out.println("失敗しました");
        System.out.println(status);    
        System.out.println(result);
    }
});

これは架空のコードですが、このようなスタイルのライブラリはたくさんありますので、慣れておきましょう。

@Overrideという記号が初めて登場しました。これはアノテーションと言うもので、プログラムにつける印です。様々な場面で使用しますが、@Overrideアノテーションは、継承してメソッドを上書きしていることを示すものです。必須ではないため前回は省略しましたが、付けないとコンパイラ警告が出てしまいますので、今回からは付けることとします。

関数オブジェクト

その2: Template Method パターン

関数オブジェクトと似たような用途として、クラス継承を活用して、処理を記述する方法もあります。

これも、架空のクラスですが、例えば、画面があって、OKボタンを押した時に何が起こるかはプログラミングできるようになっているライブラリが合ったとします。

SampleScreen s = new SampleScreen() {
    public onClickOkButton() {
        System.out.println("ボタンが押された!!");
    }
};
s.show();

このような、クラス継承を利用して、一部分のメソッドだけサブクラスに委ねるテクニックを、Template Method パターンと呼びます。

テンプレートメソッド

その3: ラッパーオブジェクトパターン

例えば、以下のコードは今まで「おまじないです」と言われていたと思います。

BufferedReader reader = new BufferedReader(new FileReader("data.dat"));

これは、FileReaderというクラスをBufferedReaderクラスが包みこんでいます。BufferedReaderのような、内部にオブジェクトを包み込むオブジェクトのことを「ラッパー(Wrapper)オブジェクト」と呼びます。楽器のラッパじゃないですよ。●ランラップのラップです!

FileReaderは、ファイルを読み込むことができますが、バッファリングの機能はありません。一方、BufferedReaderはバッファリングの機能はありますが、自らファイルを読み込む機能はありません。

そこで、BufferedReaderでFileReaderを包み込むことによって、バッファリングしながらファイルを読み込むことを実現しています。

どんなにオブジェクトを包み込んでいても、外側から見ると内側は隠蔽されています。そして、インターフェースさえ一致していれば、内側に入れるものを切り替えてもプログラムが動きます。

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in);

どんなときに、ラッパーオブジェクトを作るのでしょうか?主に次のようなとき作られます。

  • 内側のクラスのインターフェースを変換して、別のインターフェースとしてAPIに渡す
  • 内側のクラスの動作に付加機能を付け加える

このように、ラッパーオブジェクトはプログラムをとても柔軟にするテクニックです。

ラッパーオブジェクト

その4: Factory

クラスからインスタンスを作るとき、

new クラス名();

と書くと説明してきました。しかし、オブジェクト指向の世界で、newはわりと嫌われ者です。何故かと言うと、これまでのテクニックの真髄はクラスを切り替えることにあります。

SoundsMaker s = new Cat();
s.makeSounds(); // ニャー
SoundsMaker s = new Dog();
s.makeSounds(); // わん

せっかくSoundsMakerインターフェースを抽出しているのに、プログラムの中に new があるため、動作が決定してしまいるのが良くないとされます。

そこで、newをなるべく隠蔽しようと言うテクニックとしてFactoryパターンというものがあります。

例えば、newを直接書かず、メソッドにしてしまうアイデア

public static SoundsMaker getSoundsMaker(String name) {
    if ("tama".equals(name)) {
        return new Cat();
    }
    if ("pochi".equals(name)) {
        return new Dog();
    }
    return null;
}
SoundsMaker s = getSoundsMaker("tama");
s.makeSounds(); // ニャー
SoundsMaker s = getSoundsMaker("pochi");
s.makeSounds(); // ワン

getSoundsMakerのプログラムを見なかったとしたら、呼び出し元は何のインスタンスが作られるか分かりません。しかし、そんなことを知らなくても、SoundsMakerインターフェースであることは保証されているので、その範囲でできることは安心して使うことができます。

ファクトリー

その5: MVCモデル

これは考え方であって、コード例はありません。ざっと覚えておいてください。

一般的に比較的大きなプログラムを書くときは、次のように分割すると良いと言われています。

役割
モデル ロジックを担当
ビュー 表示を担当
コントローラ ユーザーの操作に応答し、モデル・ビューを操作する

例えばAndroidで言えば、Activityクラスはコントローラです。もしActivityに全部のプログラムを書いてしまうと、だんだん巨大になってしまいますので、必要に応じて、モデルを切り出すと全体の見通しが良くなります。

ビューは、レイアウトの部分で、同じActivityに異なるレイアウトファイルを与えても動く点でAndroidはビューとコントローラについて抽象化されていると言えます。

MVCモデル

その6: モックオブジェクト

最後に、モックオブジェクトについて説明します。

「モック」:モックアップ(mock up)とは、店頭にある展示用模型のことです。本物ではありませんが、本物のような見かけをしています。

プログラムを作っていると、「Aというオブジェクトを使用するにはBというオブジェクトが必要」「Bというオブジェクトの初期化にはCという情報が必要」「CはAndroid実機じゃないと取得できない」などのように、芋づる式に、あらゆるオブジェクトがからみ合ってくることがあります。

しまいには、非常に大きなオバケのような存在になってしまい、一箇所変更すると、どこに影響するのか全然わからなくなることがあります。

この問題を回避するために、本物ではない、仮のオブジェクトを作って動作確認を行うというテクニックが行われます。

そのためのオブジェクトを「モック」あるいは「スタブ」と呼びます。スタブとは「代用品」という意味です。切り株が原義のようです。

インターフェースを使ってプログラミングがされている場合は、比較的カンタンにモックを作ることが出来ます。

interface SoundsMaker {
    void makeSounds();
}

お馴染みのこのインターフェース。実は今アナタはゲームを作っていて、そのゲームでは音を扱っているとします。そこではSoundsMakerインターフェースを継承したオブジェクトがmakeSoundsとやると実際にスピーカーから音が鳴るのです。

class Bomb implements SoundsMaker {
    void makeSounds() {
        // 複雑なプログラム
        // 結果的にスピーカーから音が鳴る
        // 「ドカーン!!」        
    }
}

しかし、Bombクラスを動かすためには、どうやら専用のハードウェアがないといけないそうです。

でも、音を鳴らす以外の部分は、どうやら普通のパソコンでも動かせるみたいです。

そんな時は、モックオブジェクトの出番です。

class BombMock implements SoundsMaker {
    void makeSounds() {
        System.out.println("ドカーン!");
    }
}

Bombクラスの代わりにBombMockクラスを使用するように切り替えれば、特殊なハードウェアがなくても、プログラムが動くようになります。その代わり、音が鳴るタイミングで音はならず、代わりに

ドカーン!

という文字が出力されます。

本物のオブジェクトとモックの切り替えは、オブジェクトインスタンスをnewで生成するところで行わなければなりません。そのためには「その4」で説明した、「ファクトリー」を使用する検討が必要になってきます。

モックオブジェクト

まとめ

今回説明したテクニックを使う、プログラムからどんどん野暮ったさが消えて洗練されて来ていると思いませんか?

しかし、洗練し過ぎも問題です。

例えば、Factoryの説明で作った次のコードは

SoundsMaker s = getSoundsMaker()
s.makeSounds();

元の

Cat tama = new Cat();
tama.mew();

だった時のほうが、垢抜けない可愛さがあります。

洗練されたプログラムというのは、高貴でお近づきにくい存在なのです。より多くのことを知らないと読めないし、知っていてもどんな動きをするのか「実行するまで分からない」ときます。

どこまで洗練すれば良いかは、作っているプログラム次第です。一般的に大きなプログラムは、より洗練されていることが求められますが、個人で作るアプリでは、あどけない感じで作ったほうが正解だったりします。

この感覚は、実際にアプリを作って行くことで培われていきますので、実践で身につけて行ってください。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1709 0
MayaaでWebサイトのビューを実装するときに押さえておくべき基本テクニック3 – m:idを減らすテクニック https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent5 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent5#respond Sat, 05 Dec 2015 13:55:23 +0000 http://www.susumuis.info/?p=1427 これは Mayaa Advent Calendar 2015 の5日目です。昨日はMayaaでWebサイトのビューを実装するときに押さえておくべき基本テクニック2 – m:idの実装における注意点」でした。

ふう、今日で5日目ですか。25日書き続けるのが不安になってきました。でも、おかげさまで、いつもよりも多くの方に読んでいただいているようです。出来る限り途切れさせないように頑張ります。

今日は何を書きましょうかね。困ったときは過去記事の焼き直し...全く同じでも仕方がないですが、ここに書いていることでまだ書いていないことを今日は書きます。

いしがみメソッド3. m:idを減らすテクニック

mayaaファイルはxmlなので、サイズが大きくなると、XMLエディタが重くなったりします。なので、なるべくなら、m:idは減らしたいと思ってきます。

1.m:idをパラメータ対応にする

m:idを減らすテクニックとして、同じようなメソッドをパラメータ化すればまとめられることが良く有ります。

そんな時は、こんな関数を作りましょう。

function $p(name, defaultValue) {
    var attr = originalNode.getAttribute(
        Packages.org.seasar.mayaa.impl.engine.specification.SpecificationUtil.createQName(name)
    );
    if (attr != null) return attr.value;
    attr = originalNode.getAttribute(
        Packages.org.seasar.mayaa.impl.engine.specification.SpecificationUtil.createQName(originalNode.getDefaultNamespaceURI(), name)
    );
    return defaultValue;
}

使い方はこんな感じです。例えば
一昨日書いたforプロセッサーの件は

<m:for m:id="LOOP_ITEM" init="${var loopItemIndex = 0;}" test="${loopItemIndex &gt; items.size() &amp;&amp; loopItemIndex &gt; toInt($p('max'), 999999)}" max="999999">
  <m:echo>
    <m:doBody />
  </m:echo>
</m:for>

事前に次の関数をload関数で読み込む外部jsファイルなどで読み込んでおいたとします。

function toInt(s, default) {
  try {
    return java.lang.Integer.parseInt(s);
  } catch (e) {
    return default;
  }
}

使うときはこんな感じに出来ます。

<div m:id="LOOP_ITEM" m:max="10">
  ...
</div>

このようにすることで、最初の10件のみを表示することができます。

この他にも、m:ifプロセッサーに対して常に条件を逆にするパラメータを作って、逆条件のためのm:id発行を減らすこともできます。(僕はそのためにプロセッサーを作ったりします。プロセッサーの独自作成については、後日説明します。)

PathAdjusterを効果的に使う

PathAdjusterは、画像などの相対パスを自動調整して、サーバー実行時に絶対パスに変換する機能です。本来はjpgなどの画像やjsファイルなどに使うものですが、独自のロジックを追加して、リンク先のURLをいい具合に変換すると、単なるリンクではわざわざm:idを発行しなくても良くなることが有ります。

公式マニュアル - 5-9. パス自動調整の設定 を参照してパス自動調整機能をカスタマイズしましょう。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE provider
    PUBLIC "-//The Seasar Foundation//DTD Mayaa Provider 1.0//EN"
    "http://mayaa.seasar.org/dtd/mayaa-provider_1_0.dtd">
<provider>
    <pathAdjuster class="jp.example.MyPathAdjuster">
        <parameter name="enabled" value="true"/>
        <parameter name="force" value="false"/><!-- since 1.1.13 -->
    </pathAdjuster>
</provider>

そして、jp.example.MyPathAdjuster を作成しておきます。

package jp.example;
import org.seasar.mayaa.impl.builder.PathAdjusterImpl;
public class MyPathAdjuster extends PathAdjusterImpl {
  @Override
  public String adjustRelativePath(String base, String path) {
    if (path.endsWith(".html")) {
      return MyConst.SITE_ROOT_URL + "/" + path;
    }
    return super(base, path);
  }
}

実際のシステムでは色々なパス階層があると思うので、色々工夫してかけると思います。

参考PathAdjuster のカスタマイズ - marcie001のメモ

以前はPathAdjusterは、この他に、画像のタイムスタンプを出力してキャッシュに使うこともできます。。。などと以前は言っていましたが、ファイルのタイムスタンプをリアルタイムに検索するのも少なからず負荷がかかりますし、最近はcloudfrontなどのCDNを使うことも多かったりします。画像自体別サーバーに置くかもしれません。その辺り、サービスの規模や正確に合わせてください。そんな時も、PathAdjusterがプログラマブルであることが役に立つと思います。

まとめ

今回は、m:idを減らすテクニックを紹介しました。ただし、減らし過ぎにも注意してください。あくまで、デザイナーへの使いやすさを前提にしてください。

あまりやり過ぎると、結局混乱を招いてしまいます。こういう暗黙なことをやるときは、事前に説明しておきましょう。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1427 0
MayaaでWebサイトのビューを実装するときに押さえておくべき基本テクニック2 – m:idの実装における注意点 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent4 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent4#respond Fri, 04 Dec 2015 13:55:10 +0000 http://www.susumuis.info/?p=1425 これは Mayaa Advent Calendar 2015 の4日目です。昨日は「MayaaでWebサイトのビューを実装するときに押さえておくべき基本テクニック1 – タグの命名規則と実装方法」でした。

昨日は、命名規則についての注意点を説明しました。今日はそれを軸に、各m:idの実装の仕方の注意点を説明します。

いしがみメソッド2. m:id実装時の注意すること

1. LOOP系のm:idはindexには長い名前を使い、maxを十分に大きな値を設定する

m:forを使ってfor文ライクなループを作るとき、インデックスの変数はiやjではなく、長い名前をつけることをおすすめします。これは、内側に含めるm:idが使う変数にどのインデックスが利くのかわからなくなってしまうためです。

また、for系のプロセッサーはmax属性で指定した回数以上ループすると、エラーが発生してしまいます。maxのデフォルト値は256ですが、256回制限は簡単に超えてしまいます。256を超えたら出力が止まるのではなく、エラーになるので、max属性を常に10000くらいに指定するべきです。

<m:for m:id="LOOP_ITEM" init="${var loopItemIndex = 0;}" test="${loopItemIndex &lt; items.length;}" after="${loopItemIndex++}" max="10000"

別途、ユーザーに指定した回数でループを打ち切る機能を作るのがベストです。それにはテンプレート記述者にパラメータを指定される方法が必要ですので、このやり方は今後紹介します。

2. writeプロセッサーでエスケープを解除するときは全部する

m:writeプロセッサーは、標準では常に改行・XML特殊文字・ホワイトスペース文字をエスケープします。XSSの心配がない箇所で動的にタグを出力したい場合など、エスケープを解除する場合は

<m:write m:id="INFO_HTML_HERE" escapeXml="false" />

のように書けますが、m:idごとにエスケープの設定が変わると混乱を招きます。
ので、3種類のescapeは全て同時にfalseにしましょう。

<m:write m:id="INFO_HTML_HERE" escapeXml="false" escapeWhitespace="false" escapeEol="false" />

3. 混乱を招く機能を無効にする

Mayaaの標準設定では、m:id属性ではなく、id属性でもプロセッサーと紐付けられるようになっていますが、デザイナーと分業をする際に混乱を招くため無効にしましょう。

また、XPath機能は使うべきではありません。
理由としては、デザイナーから見て、暗黙の動作のように見えてしまうことがあります。これは後々必ず混乱を招きます。
パフォーマンスにも問題があるので、これも無効にしてしまいましょう。

さらに、m:injectを使ってのプロセッサーの解決も、分業する上では不要な機能なので、無効にするべきです。

よって、次のようになります。

参考: 5-6. id属性を無視する

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE provider
    PUBLIC "-//The Seasar Foundation//DTD Mayaa Provider 1.0//EN"
    "http://mayaa.seasar.org/dtd/mayaa-provider_1_0.dtd">
<provider>
    <templateBuilder
            class="org.seasar.mayaa.impl.builder.TemplateBuilderImpl">
        <resolver class="org.seasar.mayaa.impl.
                builder.injection.MetaValuesSetter"/>
        <resolver class="org.seasar.mayaa.impl.
                builder.injection.ReplaceSetter"/>
        <resolver class="org.seasar.mayaa.impl.
                builder.injection.RenderedSetter"/>
        <resolver class="org.seasar.mayaa.impl.
                builder.injection.InsertSetter"/>
<!--
        <resolver class="org.seasar.mayaa.impl.
                builder.injection.InjectAttributeInjectionResolver"/>
-->
        <resolver class="org.seasar.mayaa.impl.
                builder.injection.EqualsIDInjectionResolver">
            <parameter name="reportUnresolvedID" value="true"/>
            <parameter name="reportDuplicatedID" value="true"/>
            <!-- HTMLのidとXHTMLのidを追加しないようコメントアウト
            <parameter name="addAttribute"
                    value="{http://www.w3.org/TR/html4}id"/>
            <parameter name="addAttribute"
                    value="{http://www.w3.org/1999/xhtml}id"/>
            -->
        </resolver>
<!--
        <resolver class="org.seasar.mayaa.impl.builder.
                injection.XPathMatchesInjectionResolver"/>
-->
        <parameter name="outputTemplateWhitespace" value="true"/>
        <parameter name="outputMayaaWhitespace" value="false"/>
        <parameter name="optimize" value="true"/>
    </templateBuilder>
</provider>

余談ですが、将来ここに、独自のInjectionResolverを追加していくようになればMayaa上級者です!

4. 名前は英語にこだわらない

m:idの名前はHTMLタグの属性名として指定します。プログラマーはついメソッドを定義するときのように、英語的な名前付けをしてしまいますが、HTMLファイルが横に長くなってしまって読みづらくなってしまうので、積極的に省略しましょう。

IF_IS_MEMBER
ではなく
IF_MEMBER
とします。

5. tableタグだけは特別に扱う

tableタグはMayaaと相性が悪いタグの一つです。
divタグのように、無限に包むことが出来ず、

table > tbody > tr > td
のように階層構造が決まっているため、例えば、trタグにm:idを既に適用してしまうと、そのtrをある条件にもとづいて出し分けなどが出来ません。

ダメな例:


<table>
  <tbody>
<div m:id="IF_MEMBER">
    <tr m:id="ROW1_TAG">
      <td>aaa</td>
      <td>bbb</td>
      <td>ccc</td>
    </tr>
</div>
    <tr m:id="ROW2_TAG">
      <td>aaa</td>
      <td>bbb</td>
      <td>ccc</td>
    </tr>
  </tbody>
</table>

この書き方は出来ません。divタグをtbodyとtrの間に書くことが出来ないためです。IF_ROW3をm:echoなしのifプロセッサーにして、タグが消えるようにすれば、サーバー側では大丈夫になりますが、テンプレート側で見た時に表示が崩れてしまいます。

そこで、せっかくIF_MEMBERのように流用できるm:idがあったとしても、ROW1_TAGの方に、ifプロセッサーを追加して次のようにしてください。

<m:if m:id="ROW1_TAG" test="${context.isMember()}">
  <m:echo>
    <m:attribute name="xxx" value="yyy" />
    <m:doBody />
  <m:echo>
</m:if>

まとめ

地味なルールですが、これらを守ることであとあと混乱を防ぐということが効いてきます。

Mayaaはとても汎用的に作られていて、初期状態では、大変ゆるい状態でリリースされている印象を持ちます。

しかし、チームで作業をする場合は例えば、
InjectAttributeInjectionResolver
のようなものは使わず、必要最小限の機能で賄う戦略を取ることが結局効率が良いです。

さらに、次回はもっと面白いテクニックを紹介しようと思います。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1425 0
MayaaでWebサイトのビューを実装するときに押さえておくべき基本テクニック1 – m:idの命名規則と実装方法 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent3 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent3#respond Thu, 03 Dec 2015 13:18:08 +0000 http://www.susumuis.info/?p=1420 これは Mayaa Advent Calendar 2015 の3日目です。昨日は「JSPで書かれたシステムをMayaaに移行する」でした

さて前回の記事で、JSPでフロントが書かれたプロジェクトをMayaaに移行する例を書きました。しかし、実際にWebシステムのビューをすべて実装しようとすると大変です。

そこで、今日から数日に分けて私の経験に基づく、MayaaでWebサイトを実装するテクニックを紹介します。

自分で言うのも恥ずかしいですが、「いしがみメソッド」ってなやつです (^^;

いしがみメソッド1「命名規則は徹底せよ」

デザイナーはMayaaファイルを読めません。したがって、m:id一つ一つ何を意味するのか、意思疎通をしておくことが必須です。

1.m:id含め、プログラム都合の識別子は常に大文字を使う

Mayaaを使う最大の目的は、デザイナーとプログラマーが平行して、最終的に出力される一つのHTMLを作ることです。

したがって、同時にひとつのHTMLを作ることになります。そうすると、二人して同時にclassを作ってしまったりします。

そこで、プログラマーが書くものは常に大文字、デザイナーが書くものは常に小文字というように、命名規則を分けることを推奨します。

プログラマーが小文字、デザイナーが大文字でも良いですが、制御を扱うm:idが大文字の方が埋もれないメリットが有り、次のようなスタイルが良いです。

<div m:id="IF_MEMBER" class="member_box">
 ...
</div>

2.m:idのする仕事を4種類に限定する

僕は発行するm:idを次の4種類に限定しています。

  • *_HERE

    • その場所に文字列を出力する
  • *_TAG

    • そのタグの属性を変化させたり要素を足したりする
  • IF_*

    • そのタグ及びその子要素が特定の条件にもとづいて消える
  • LOOP_*

    • そのタグ及びその子要素を特定の条件に基づいて繰り返す

これまでの経験から、この4種類だけでWebサイトは作れ作れます。

3.それぞれの実装方法

それぞれ、実装の方法も固定されます。_HEREは、その場に出力されれば良いので、m:writeプロセッサーをそのまま使うのが良いでしょう。

<!-- タイトルを出力します -->
<m:write m:id="TITLE_HERE" value="${page.getTitle()}" />

m:writeプロセッサーではなく、m:insertプロセッサーの場合もあります。これらは、デザイン視点から見たら違いがないので、m:idの名前は、常にデザイナー視点で考えてください。

_TAGは主にタグの属性を変更するために使用します。場合によっては、hidden要素の追加にも使います。hiddenはデザインとは関係ない要素なので、テンプレートに記述することはせず、常にm:idで出すべきです。

また、属性はデザイナーが編集する場合もあり、m:idで制御する対象とデザイナーが書いた属性がぶつかると、デザイナー側の記述が無効になってしまいます。そこで、事前にどのm:idがどの属性を制御するのかわかるようにしておきます。classやid属性が変化するやつは特に注意が必要です1

<!-- 商品画像を表示します。src属性を制御します -->
<m:echo m:id="ITEM_IMAGE_TAG">
  <m:attribute name="src" value="${image.getSrc()}" />
</m:echo>

IFのm:idは、そのままm:ifプロセッサーを使ってはいけません。m:ifプロセッサーは、条件にマッチしても、自分のタグを消してしまいます。例えば

ダメな例:

<m:if m:id="IF_MEMBER" test=${context.isMember()} />
<div m:id="IF_MEMBER">
会員限定
</div>

会員限定

このようになってしまうと、テンプレート上ではdivで囲まれて前後が改行されているのに、divが消えて横並びになってしまいます。これではいけませんので。正解は次のように書くことです。

良い例:

<m:if m:id="IF_MEMBER" test=${context.isMember()}>
  <m:echo><m:doBody /></m:echo>
</m:if>

LOOPも同じことが言えます。

良い例:

<m:forEach m:id="LOOP_ITEM" items=${items}>
  <m:echo><m:doBody /></m:echo>
</m:if>

4._TAGの運用な慎重に

これら、4つのルールの中で、*_TAGは唯一汎用的に使うことができます。それは、IFのようにも、_HEREのようにもできます。

このことは、コンポーネント的なm:idを作れる反面、きちんとドキュメントを書かないとデザイナーとの間で混乱を招きます。

例えば、ある時「条件に応じて、display:noneで表示非表示を切り替えられる領域」という意味で「**_AREA_TAG」というものを作りました。
「エリアタグとはなんぞや」
というクレームが上がりました。どうしても、特殊な概念のTAGを作りたければ、事前にネゴっておきましょう。

実際は_INPUT_TAGや、_RADIO_TAG、*_IMAGE_TAGのように指定するべきタグ名と名前を合わせるのが無難な選択です。

ただ、必ずしもタグ名がデザインとシンクロするとも限らないので、この辺りは事前に話し合って決めましょう。

default.mayaaに書いたm:idには接頭辞"common."を付けよう! (2015/12/07 追記)

default.mayaaに書いたm:idはすべてのテンプレートファイルで使えます。これらと各ページ特有のm:idは名前で見分けられるほうが良いです。

ということで、僕は"common."という接頭辞を付けています。

<span m:id="common.SITE_NAME_HERE">サイト名</span>

まとめ

ざっと命名規則について、説明させていただきました。

まとめてみると、常に、同じリソースを、プログラマーとデザイナーが同時に書いているということを意識することが大切です。

Mayaaという技術の採用はプログラマー側が引っ張って導入しているものなので、プログラマーは是非自分の範囲以上に、チーム全体のことを考えてm:idの設計を行ってください。

Mayaaの導入で最も重要なのはチームワークです。明日以降もチームワークを支える様々なテクニックを紹介します。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1420 0
WindowsでJavaな人に捧げる素敵なスクリプティングツール jrunscriptの使い方 https://susumuishigami.github.io/susumuisinfo/entry/2015/java_advent3 https://susumuishigami.github.io/susumuisinfo/entry/2015/java_advent3#respond Wed, 02 Dec 2015 15:00:20 +0000 http://www.susumuis.info/?p=1443 これは Java Advent Calendar 2015 の3日目です。昨日は@kawasima さんの「Webアプリ開発/テストのお供に『WAITT』」で、明日は @akihyro さんです。

もしもLLが使えたなら

業務にWindowsを使用していて、開発言語はもっぱらJava、LLを使えたらかっこいいと思うけど、Windowsだし。。。。Powershellとかよく知らないしでもっぱらサクラエディタ、、、そんな方はいらっしゃいませんか?

僕は、そんなあなたを応援します!なぜなら僕がそうだからです!

僕は大量のファイルを作ったり、複雑なファイル検索をしたいなどのデータ処理に、よくJDK付属のjrunscriptコマンドを使っています。例えばこの記事でも使っています。

jrunscriptとは

jrunscriptはJDK6以上に付属しているコマンドで、JVM上でJavaScriptエンジンを実行することが出来るコマンドラインツールです。cd()やdir()などの若干のシェル的な組み込み関数をバンドルしています。

JavaScriptなら、Web開発を経験していれば、Javaばかりの人も自由に書けるのではないでしょうか?

Javaプログラマーがjrunscriptコマンドを使いこなすメリット

  • JDKさえ入っていれば、WindowsでもMacでもLinuxでも動く
  • 使い慣れたJavaAPIが使える

冒頭に述べた僕みたいな人にぴったりなツールです。確かに、LLに比べてJavaScriptはfunctionなどの入力量が多いです。

しかし、APIを調べたり、言語仕様を勉強している時間がほぼいらないので、やりたいことが最短で実現できます。

しかも、LinuxやMacにそのまま持っていけます!やった\(^o^)/

JVMの状態を見よう

jrunscriptのもう一つの用途として、即座にJavaのシステムプロパティどうなっているんだっけ?など、JVMの状態をしれてしまうことがあります。

$ jrunscript -e "print(java.lang.System.getProperty('user.timezone'))"

システムプロパティを列挙するならこんな感じです。

$ jrunscript -e "for (var key in java.lang.System.properties) print(key + "-" + java.lang.System.properties[key]);"

組み込み関数を知ろう

次のURLに記載された関数が組み込まれています。
http://docs.oracle.com/javase/7/docs/technotes/tools/share/jsdocs/GLOBALS.html

これらの関数は地味ながら、時々役立ちます。例えばjrunscriptで簡単なインストーラーを作るときなどは重宝すると思います。

JavaとJavaScriptの橋渡し

JavaAPIを使ってしまうと、Javaの配列を受け取ったりします。Nashorn/Rhinoの世界では、JavaScriptの配列とJavaの配列は明確に区別されており、JavaScriptとして使うならJavaScript配列を使ったほうが便利です。

例えば、次のようにES5風のforEachが書けます。

nashorn> [1,2,3,4,5].forEach(function(i){print(i);})
1
2
3
4
5

しかし、Java配列の場合はできません。

nashorn> new java.io.File(".").list().forEach(function(i){print(i);})
script error: TypeError: [Ljava.lang.String;@5a63f509 has no such function "forEach" in <STDIN> at line number 1

この場合は、Java.fromというメソッドが使えます。

nashorn> Java.from(new java.io.File(".").list()).forEach(function(i){print(i);})
aaa.txt
bbb.js
xxx.zip

応用編

あるディレクトリ以下の全てのファイルを探索

これはよく使うのでイデオムではないでしょうか。

function f(i) {
    if (i.isDirectory()) {
        Java.from(i.listFiles()).forEach(function(e) {f(e);})
    } else { doSomething(i) }
}
doSomething = function(i) {print(i);};
f(new java.io.File("."));

以下、このfを定義していたとします。

例題1. あるディレクトリ以下で、拡張子がjavaのファイルで10日以内に変更したファイル一覧を取得

doSomething = function(i) {
    if (i.lastModified() > java.lang.System.currentTimeMills() - 1000 * 3600 * 24 * 10) {print(i);}};
f(new java.io.File("."));

例題2. あるディレクトリ以下で、ファイル名がAdminから始まっているファイルの容量の合計

doSomething = function(i) {
    if (i,getName().startsWith("Admin")) {print(i.length()); sum += i.length()}};
var sum = 0; f(new java.io.File(".")); print(sum);

例題として微妙ではありますが、関数を組み立ててやりたいことを実現していくのが気持ち良くなってきませんか?

まとめ

このように、JDKさえあれば使える、クロスプラットフォームなスクリプティングツールとして、いざというときに役立つのではないでしょうか。

Java6がリリースされてから9年経ちますので、9年前以降のしすてむであったら使うことが出来ます。

JavaAPIが使えるので、いちいち慣れない言語のAPIを調べる手間が省けるのが嬉しいです。あれ、これ、Rubyではどう書くんだろう?と思う必要がありません。

また、ある程度うまく行ったら、Javaで同等なことが出来るので、本番のコードとして流用することもあるかも知れません。

これで、LL弱者の僕も、ワンライナーを駆使できるようになりました。

次はあなたの番です!

jjsコマンドについて

jrunscriptの他に、Java8からはjjsというコマンドが搭載されています。jrunscriptは試験的に作られたコマンドという位置づけなので、本来はjjsコマンドを使うべきです。

しかし、標準組み込み関数が微妙に異なることと、java6,7環境も依然として存在すると思われますので、僕はjrunscriptを好んで使います。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1443 0
JSPで書かれたシステムをMayaaに移行する https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent2 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent2#respond Tue, 01 Dec 2015 15:00:43 +0000 http://www.susumuis.info/?p=1416 これは Mayaa Advent Calendar 2015 の2日目です。昨日は「Mayaaとの出会い」でした。

JSPで書かれたシステムのMayaaへの移行

さて、前回、MayaaはJSPと同じレイヤーで動いているから、JSPでデザインが描かれているシステムは簡単に移行できると書きました。

今回は実例を元に、その様子を解説しようと思います。

何でも良いので、JSPをビューに使っているMVCフレームワークがあるとします。

例えばこれは、SAStrutsのコード例です。

import org.seasar.struts.annotation.Execute;
public class IndexAction {
    @Execute(validator = false)
    public String index() {
        return "index.jsp";
    }
}

今から新規にStrutsのコードを書くことはないと思いますが、StrutsライクなMVCフレームワークなら何でも同じようにできると思います。自分の使っているフレームワークに脳内変換してください。
(後日、最近のメジャーなフレームワークとMayaaを連携する例を書きたいと思います。)

MayaaServletをweb.xmlに登録

もし使っているのが、レガシーServletでWeb.xmlを書いているなら、次の設定を書き加えましょう。

    
    <servlet>
        <servlet-name>MayaaServlet</servlet-name>
        <servlet-class>org.seasar.mayaa.impl.MayaaServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>MayaaServlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

<url-pattern>*.xhtml</url-pattern>という部分は、標準のMayaaの流儀ではないかもしれません。しかし、多くのWebシステムは既にhtmlをマッピングしているのではないでしょうか?私の現場もそうでした。そこで私はxhtmlファイルをMayaaのテンプレートとして設定しました。その結果、テンプレートファイルは正しいxhtml書式で書く文化がチーム内に浸透したため、良い判断だったと思います。

あとは、Java側でフォワードしている部分のJSPの部分を

import org.seasar.struts.annotation.Execute;
public class IndexAction {
    @Execute(validator = false)
    public String index() {
        return "index.xhtml";
    }
}

のように書き換えましょう。後はindex.jspの代わりにindex.xhtmlを置くだけです。

この方法の良い所は、JSPとMayaaを同居できることです。移行作業中は、古いJSPのテンプレートも残すことが出来ます。ただし、JSPにMayaa、MayaaにJSPをインクルードすることは出来ませんので、そのあたりはご注意ください。

テンプレートを書く

次にテンプレートを書きましょう。例えばJSPがあったとします。ちなみに、僕はJSPのtaglibが嫌いで、ほとんど使いません。なので、MayaaにもJSPのtaglibをサポートする機能を持っていますが、全然使ったことがありませんので、公式のマニュアルを参照してください(笑)

ちなみに、EL式も使いません。何か文句ありますか?

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="info.susumuis.sample.ViewHelper" %>
<%@ page import="info.susumuis.sample.SampleBean" %>
<% SampleBean bean = (SampleBean) request.getAttribute("bean"); %>
<html>
<head>
  <title ><%= ViewHelper.escape(bean.getTitle()) %> </title>
</head>
<body>
<%= ViewHelper.escape(bean.getMessage()) %>
</body>
</html>

ViewHelper.escapeは、HTMLエスケープをする共通メソッドだと思ってください。

これをMayaaに移植する最も手っ取り早い方法は、JSPを実行した結果のHTMLをいきなり貼り付けてしまうことです。

 



<html>
<head>
<title >たいとる</title>
</head>
<body>
ハローワールド
</body>
</html>

このままでは文字化けしてしまいますので、metaタグで文字コードを指定します。Mayaaはmetaタグでコンテントタイプを設定しておくと、勝手にヘッダを書き換えてくれますので活用しましょう。

このとき、注意として、HTML5の、<meta charset="">を使わないことです。使っても良いのですが、text/html;の部分の情報が抜けてしまうので、以下のように古い書き方を使うことをおすすめします。

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

また、JSP特有の空行は消していきましょう。また、拡張子をxhtmlファイルにしてしまったので、ブラウザでプレビューできるようにxmlns指定を書きます。本当は先頭行に宣言が必要ですがこれはサボっても表示できるようです。(この辺りは、MayaaがContent-Typeを見て最終的に適切な出力に調整してくれます)

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title >たいとる</title>
</head>
<body>
ハローワールド
</body>
</html>

このテンプレートはWebブラウザでそのまま開くことが出来るはずです。

これで、サーバーで実行するのと同じ出力を得ることができますね。

え、動的な部分が固定されてしまっている?その通りです。しかし、Mayaaのページ作りの流儀としてはこれでよいのです。この後の説明を読めば分かります。

動的部分を実装する

元のコードはSampleBeanから、タイトルとメッセージを取得していましたね。Mayaaでは動的な出力を実現するために、m:idというものを使います。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://mayaa.seasar.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title m:id="TITLE_TAG">たいとる</title>
</head>
<body>
<span m:id="MESSAGE_HERE">ハローワールド</span>
</body>
</html>

htmlタグに名前空間xmlns:mを追加しています。
m以外を指定しても動きますが、普通はm:に割り当てます。"m:id"は「エム・アイ・ディー」と読みます。Mayaaの世界では非常に多用する単語なので、覚えましょう。

動的にしたいタグにm:idを加えていきます。もともとタグがなかったところはspanタグで補います。

ところで、Mayaaは非常に柔軟ですが、自由に使い過ぎると、デザイナーさんとの連携をスムーズにできません。お互いにある程度ルールを定めるべきです。そこで、僕はm:idは次の4種類に限定しています。

  • _HERE

    • その場所に文字列を出力する
  • _TAG

    • そのタグの属性を変化させたり要素を足したりする
  • IF_

    • そのタグ及びその子要素が特定の条件にもとづいて消える
  • LOOP_

    • そのタグ及びその子要素を特定の条件に基づいて繰り返す

m:idを発行するときは、出来る限り、HTMLとしてvalidになるように心がけましょう。
例えば、tableタグの中に、divタグを入れたり、titleタグの中にspanタグを入れるのは無しです。そのようなことをすると、Mayaaの良さを喪失してしまうので気をつけてください。

このままページを出力してみましょう。
ローカルでそのままダブルクリックしてブラウザに表示させても、サーバーで実行させても相変わらず表示は同じです。

mayaaファイルを書く


<m:mayaa xmlns:m="http://mayaa.seasar.org">
    <m:beforeRender>
        var bean = request.bean;
    </m:beforeRender>

    <!-- タイトルタグです -->
    <m:echo m:id="TITLE_TAG">
        <m:write value="${bean.getTitle()}" />
    </m:echo>

    <!-- メッセージを出力します -->
    <m:write m:id="MESSAGE_HERE" value="${bean.getMessage()}" />
</m:mayaa>

このようにm:idの動作を記述していきます。実は命名規則を定めたので、これらの書き方はある程度定型化できます。Mayaaはm:idだけ定義しておいて、mayaaファイルに実装していないとログにエラーメッセージを吐くので、エラーメッセージから雛形を出力するマクロを作るのも良いでしょう。僕も過去に作りました。

Mayaaファイルを命名規則から一括作成するEmEditorマクロ

本当は、標準のm:write, m:ifなどは使い勝手が悪いので、自分でプロセッサーを作ることをおすすめします。これについては、後日ご紹介します。

もう一つ、JSPのコードからViewHelper.escapeの記述が消えました。Mayaaでは、出力をエスケープするのがデフォルトの動作です。なので、「必要に応じてエスケープを解除する」というスタイルになります。昨今脆弱性が対策は必須となっていますので、この流儀は大変便利です。

このようにして1ページの移行が完了しました。あとは、全てのページを同じように移行していくことです。

しかし、実際のページはもっと複雑で、難しいことも多いと思います。次回から、個別にハマリポイントとその回避方法を紹介して行こうと思います。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1416 0
Mayaaとの出会い https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent1 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent1#respond Mon, 30 Nov 2015 15:00:39 +0000 http://www.susumuis.info/?p=1414 今日からMayaaについての記事を書いていきます […]]]> これは Mayaa Advent Calendar 2015 の1日目です。

明日は @susumuis の「JSPで書かれたシステムをMayaaに移行する」です。-->

今日からMayaaについての記事を書いていきます。

Mayaaってなに?

Mayaaはエンジニアとデザイナーとの連携を強く意識して設計されたJavaテンプレートエンジンです。

Mayaaを使用したプロジェクトが上手くいくと、Webデザイナーはプログラムを意識することなく、Webアプリケーションのデザインコーディングをすることができ、プログラマーはHTMLやJSPなどのコーディングから開放されます。

お前誰?

初めてこのブログを読んでくれた方には申し遅れました。私は、2009年より、仕事でMayaaを使用していて、2015年よりMayaaコミッターの末席に名を連ねさせていただいたものです。

おそらく、現在私が関わったプロジェクトが、Mayaaを使用した最も大規模なシステムの一つではないかと思っています。なので、どちらかと言うとMayaaの開発者視点というより、ユーザー視点の方が強いです。

Mayaaとの出会い

先ほど述べたとおり、2009年に自分の仕事でMayaaを利用し始めました。既にリリースから数年経過していますから、少し遅いほうだと思います。

当時、私は、ECサイトシステム構築におけるプログラミングコストの削減と、デザインテンプレートの充実化を課題として持っていました。

そこではじめはApache Wicketを試してみたのですが、確かにWicketは素晴らしいアーキテクチャでしたが、プログラミングの考え方がガラッと変わりすぎてしまい、既存の資産の活用が困難であるとわかり、導入を見送りました。

Wicket導入を振り出しに戻し、次にMayaaを検討することにしました。当時はまだThymeleafやMixer2はありませんでした。

Mayaaの導入がうまく行った理由

嬉しいことにMayaaの導入は非常にスムーズに行きました。それは、Mayaaが、システムの構成上、JSPと同じレイヤーに位置づけられるように設計されているため、他の部分を変える必要が一切なかったことです。

JSPファイルの横にxhtmlファイル(Mayaa標準ではhtmlを推奨していますが、htmlは既にフロントのサブレットに割り当てられていました)を配置して、.jspへフォワードする代わりに、.xhtmlへフォワードするだけで、後は、テンプレートを書くだけで移行が完了してしまいました。

mayaa_jsp

バックオフィスツールなど、デザインが重視されない部分については従来通りJSPを維持することも可能でした。

このようにアーキテクチャの変更をほとんどすることがなく、JSPから移行ができたことが、最大のメリットだったと思います。

次回予告

次回は、JSPで書かれたテンプレートをMayaaによるテンプレートに移行するときの手順、ハマったことなどを書こうと思います。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1414 0
Seasar Conference 2015に参加してLTをしてきました #seasarcon https://susumuishigami.github.io/susumuisinfo/entry/2015/seasarcon https://susumuishigami.github.io/susumuisinfo/entry/2015/seasarcon#respond Sun, 27 Sep 2015 13:19:52 +0000 http://www.susumuis.info/?p=1389 2015/09/26、5年ぶりに開催された、
Seasar Conference 2015 Not 同窓会
に参加し、次のスライドでLT登壇してきました。

なぜLTをしたのか

僕はこれまでにもMayaa関係の勉強会登壇を繰り返してきました。

JJUG CCC 2013 Fall: テンプレートエンジンを利用してプログラマーとWebデザイナーが共同作業をする上で大切なこと
JJUG ナイトセミナー 2013/08: from JSP to Design-friendly Template Endine JSPからMayaaに移行した本当の話

このブログでも、Mayaaについての発信が多めです。

5年間Mayaaを使って思ったこと
Mayaaでm:idの解決の仕方を自分好みにカスタマイズする方法
MayaaなどRhinoを使っていてハマること。It is not a function, it is String
2年間Mayaaを使ってわかったこと その2
そろそろ2年間Mayaa使ってわかったことを書く
MayaaでHTML5のスマートフォンページを作る際にはまったこと
Mayaaファイルを命名規則から一括作成するEmEditorマクロ
MayaaでGuice2.0 AOPを使うとうまく動かない件〜解決編
MayaaでGuice2.0 AOPを使うとうまく動かない件

Mayaaは、自分が大変お世話になっているOSSで、不具合報告などでOSS活動にも関わらせていただくなど、技術者として成長させてもらった思い入れの強いライブラリです。

この日、作者である栗原 傑享さんや、現在メインコミッターを務められる須賀 幸次さんがいらっしゃるということで、彼らへの感謝の気持ちを表現したいという、実に個人的な動機がLTをした理由でした。

それにしては、Seasar Foundationの重鎮の方々に好意的に受け入れて頂いたようです。考えてみるとMayaaが生まれた土壌である、Seasarコミュニティの存在も肯定する内容でもあったからかなと思います。そういったわけでは、Seasarコミュニティーに対しても感謝の気持ちを明確に表すべきでした。この場を持って、感謝の意を表明致します。

なぜ今SeasarConなのか?

Seasar Conference は2010年を最後に開催されず、Seasar2も既に機能の追加が中断されていました。既に、JavaのトレンドはSpringやJava EEに移行しており、Seasarは時代の中でフェードアウトしたように見えていました。その中で、なぜ?今 Seasar Conference なのか?と多くの方が興味を持ったと思います。

蓋を開けてみると、5年前まで、あんなに先導的なメッセージを発信して日本のJava系エンジニアの最大のカリスマだったひがやすをさんが、どうも、中立的というか、大人な話し方をされている印象でした。まして、Seasar2のサポート終了(2016/09/26)を宣言される。あれあれ、なんか暗いぞ??

そこへ栗原 傑享さんの喝が入ります。どどどんな展開((((;゚Д゚))))ガクブル

5年間Seasar Conferenceが行われなかった裏で何が起きていたかについては、理事長の橋本さんのセッションで説明がありました。開催されなかった理由:

  • イベント駆動開発→開発駆動イベント→DIのメンテナンス終了、ワクワク感より調整の難易度が上回った
  • NPO運営はスポンサーに支えられている。ムーブメント、流行に乗る必要がある
  • NPO改名問題があった

NPO活動を行うにも、イベント一つ行うのも、裏での苦労が絶えないのだなあということが伝わりました。その一方で、福岡の方では「明星和楽」というイベントが行われ、これは「テクノロジーとクリエイティブ」にフォーカスしたイベントで、業界の流れがSIからスタートアップに向かう中での実験として成功だったそうです。

自分は新参者なので、知りませんでしたが、Seasarコミュニティを支えていた方々は、SIerの精鋭たちが中心であって、SeasarとSI・受託開発という枠組みは切っても切れない存在のようです。2010年頃には、ひがさんはSlim3をリリースしていてAppEngineなどでのスタートアップ志向にシフトしていたし、橋本さんの経営されるヌーラボは、Cacooなどのサービスを打ち出していたので、どちらかと言うと、サービス指向をもともと持っていた人たちだと思っていましたが、SIにおける、エンタープライズJavaからのニーズがSeasarの原点だったのです。

2010年から、2015年の間に震災やスマホブーム、ソシャゲブーム、クラウドの興隆を経て、今時「受託かスタートアップか」という議論自体が古臭いと思いますが、Seasarというコミュニティは、その原点と、その名前が足かせとなって、進むべき方向性に難儀していたそうです。こういうことを赤裸々に話してくれたことに大変感謝します。

個人的には、僕のような、当時接点を持てなかった者がかつてSeasarで有名だった方々と繋がることができたのが大変ありがたく思いました。懇親会にも参加させていただきましたが、これからどうするのかというような議論が活発になされているようです。解散か?改名か?なにかの転換があるのか?Seasarの次の動向に期待したいです。

栗原さんの海外のIT事情の発表が面白かった

Mayaaの開発者にして、グルージェントの創業者で、サイオスの幹部として、現在はシリコンバレーに生活されてスタートアップをされている栗原 傑享さんの発表は刺激的でした。

アメリカでは、徹底的に生活の効率化が行われて、公共インフラが民間企業の寡占状態にある。例えば、警察を呼べばお巡りは来ずに、メールアドレスを聞かれて、CoplogicというWebサイトから被害届を出すように言われる。そのCoplogicは民間企業!部屋を探すときはcraigslistが必須。Coplogicもcraigslistもナニコノ垢抜けないデザインは!

「少年野球はミスも出やすいですから、基本積極プレーで」(引用:MAJOR 2nd 第25話)

これがアメリカのスタートアップのメンタルのようです。僕たちは、FacebookやGoogleといった超巨大な企業しか知らないために、すごいイメージがありますが、あれはメジャーリーグ、シリコンバレーのスタートアップは大半が少年野球!(マイナーリーグですらないのか。。。)彼らはCSSも書かずに平気で2塁まで突っ込んでいくんだそうです。

このメンタルでくると、要件定義をして、スケジュールを引いて、アサインして……のやり方では間に合わないのは確かですね。

前述のように、アメリカは公共インフラが徹底的に効率化され、民間企業の寡占状態にあります。この状況は、間違いなく未来の日本にもやってくる!今のうちにcraigslistをパクったら儲かるwwwまあ、100パーセント同じにはならないと思いますが。(^^;

個人的な考察:2010年から2015年という時代について思うこと

稚拙な考察ですが、2010年ごろ不況もあり、業務システムのIT化も既にコモディティ化が済んでしまった以降、今までの形態のSIerのニーズは減少し、クラウドなど黒船の到来によって、この世界は縮小するのは明らかでした。

では、多くのITエンジニアが職を失ったのかといえば全く逆で、未だに「エンジニアが足りない」と言っている。何が起きたかといえば、これまでよりも多くのことにWebやスマホなどのITが使われるようになった(リアルなお店でものが売れなくなった)と言われます。

しかし、この業界の流動性は非常に速く、今までみたいにじっくり良い物を作っていくより、手が早い方が求められました。そうすると、1からスクラッチでシステムを作るより、WordPressを改造して目的を実現するとか、既存の何かをいじって楽をできる方が重要で、そうなってくるともう言語やフレームワークがどうこう言っていられない。WordPressに乗っかるのか、Google Appsに乗っかるのか?

ただ乗っかっているだけだとプラットフォーマーに吸い取られる仕組みになっています。そこで自ら何らかのプラットフォーマーになるか、あるいはレベニューシェアなど成果にコミットする方向性がこれから成功する秘訣なのかなあと思います。

そう考えると、2010年と今とでも時代は全然違うなあと思います。

ここまで理解したところで、何もできていない自分に比べたら、Seasarの中心の方々は僕よりも何十倍も優秀な方々の集まりなので、一人ひとりはこの波の中で成功されているのでしょう。でも、Seasarという糊がなければ、彼らはつながらずSeasarは時代の流れの中で役割を終えようとしている中で、外部の者がどうこう言うことではありませんが、同窓会だったとしても十分に価値があったと思います。そこに行って、憧れの彼らが今どうしているのか、話を聞かせてもらえたことは、新参者の自分として、大変刺激的で大変貴重な一日でした。

今、自分の年齢はSeasarの人たちが活発に活動をされていた年齢くらいに位置します。同世代のエンジニアを見渡すとSeasarを作る人は出てこないだろうなあと思いますが、CEOやCTOを名乗っている友人もいますし、ある意味、スタートアップ時代を生きています。そんな中で、僕らは、一まわり上の方の貴重な経験をもっと吸収して、自分たちこそ時代を盛り上げていかなければならない時ではないでしょうか。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1389 0
Windows8タブレットを買って再会した二次元の「幼なじみ」たち https://susumuishigami.github.io/susumuisinfo/entry/2014/windows_tablet_games https://susumuishigami.github.io/susumuisinfo/entry/2014/windows_tablet_games#respond Sat, 30 Aug 2014 14:42:16 +0000 http://www.susumuis.info/?p=1138 僕はモバイル機器を買うと必ず「幼なじみに再会」できるかどうかを試すという儀式的なことを行います。ツッコミはご自由にしてください。何を言われても屈しません。

先日、Windowsタブレットを買いました。
数ある中から僕はLenovo IdeaPad Miix2 8を選びました、

今回はWindowsということで、取り立てて苦労することなくゲームが動くだろうと思ったら結構動きませんでした。せっかくなので結果を報告します。

ところで、このブログはGoogleアドセンス広告を掲載させて頂いているため、いわゆる18禁はNGと思われます。なので、メイドロボットが出てくる昔の葉っ(ryとかいうことを書くことは許されないと思いますので、諦めて全年齢向けの作品のみの情報を扱わせていただきます。

(キャプチャ載せようともしましたが、めんどくさいし、著作権的な問題もあるので省略します。タイトル覚えてる人は脳内補完をよろしくお願いします)

Kanon全年齢版

言わずもがな。定番ギャルゲブランドKeyの代表作、ヒロインの名雪さんが最初のシーンで「再会のお祝い」っていうんですね。状況的にバッチリですね!ちなみに、いきなり文字化けしましたが、フォントを変更することで、文字化けはあっさり直りました。

Air全年齢版

状況はKanonと同じ感じでした。エンジンのバージョン的にも近いのでしょう。

CLANNAD

ストレスなく動きました。いわゆる「クラナドは人生」とか。僕はごめんなさい。最後までやっていないので、せっかくなのでそのうち、攻略しようと思います。

センチメンタルグラフティ

全国に散らばるえっと13人でしたっけ、女の子に会うためにバイトでお金を稼いでヒッチハイクの旅をするという、どうしてこうなったのかよくわからない迷作ですね。僕はえみりゅんが好きりゅん。

これはXPのころから、オープニングは見れないから、初期データをでっち上げるという技で起動はしたのですが、なんだかフォントサイズがずれてしまって見るに耐えない状況でした。

エーベルージュ2

このシリーズがなければ僕はこの世界を知らないまま学生時代を過ごしたに違いない。その二作目、前作よりもストーリーがキビキビしてて良かったです。メルさんが好きでした。起動することは確認しましたが、キーボードがないと、ゲームを終わらせる手段がなさそうです。これでは困ってしまうので二度と起動することはないでしょう。

ファンタスティックフォーチュン

僕がやった唯一の乙女ゲー、乙女ゲーといえど主人公の姫さんが可愛いくて、声優の茶山莉子さんの名前まで覚えてしまった程に、大変満足できた作品でした。が、動きませんねー (T_T)

Zweii

ギャルゲじゃないけど、Falcomが作ったキャラがかわいいアクションRPGゲーム。
主人公兄妹に会えたら嬉しかったんですが、いきなり起動しませんでした><

他にも、いくつかのゲームを動かそうとしてみましたが、どうも動かないことが多かったです。寂しいというかなんというか。まあ、そんなものでしょう。どうせ、外に持ちだしていって、公衆の前でにやにやしながらプレイするわけにはいかないので、容量ももったいないし消しちゃいました。

結論

幼なじみにいつまでも逢えるってものじゃないのです。きっと、みんなそれぞれの人生を歩んでいったのでしょう。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1138 0
Let’s Go! #Golang勉強会 Vol.1に参加してきました https://susumuishigami.github.io/susumuisinfo/entry/2014/letsgolang https://susumuishigami.github.io/susumuisinfo/entry/2014/letsgolang#respond Sun, 27 Jul 2014 12:53:48 +0000 http://www.susumuis.info/?p=1123 勉強会と Co-Edo について

コワーキングスペース茅場町 Co-Edoで行われたGo言語の勉強会Let's Go! #Golang勉強会 Vol.1に参加してきました。Co-Edoは去年はじめてのgit勉強会&もくもく会 に参加させていただいたのが初めてでその後利用していませんでしたが、オーナーの田中さんににはその後Facebookでつながっていただいていたので、もう一度利用したいと思って思っていました。

今日の勉強会は、コワーキングスペースの片隅机1,2卓を囲んで参加者4,5人の小さな勉強会でした。僕以外の人はGo言語経験者みたいです。僕は今日はじめてインストールしました。

Go言語について

Go言語といえば、Googleが作っている新しいプログラミング言語です。コンパイル式でバイナリを出力できるのが特長で、C++をより開発しやすくしたような立ち位置です。そのため、速度を求められる領域での利用が多く、事例としては、Dockerなどがあります。Gunosyのインフラで使用されていることも有名です。僕のTwitterのTimelineの中でもやっている人をちょくちょく見かけるようになりました。

初めて触ったGolangの印象

半日触ってみた印象としては、今からC++を勉強するよりは学びやすい印象を受けました。文法はCやJavaのようでpythonのようなLLの影響も受けている少し独特な記述の言語ですが、使っていればすぐに馴れそうです。

Webフレームワークもありますが、まだ企業で利用するほどには安定していないようです。

しかしライブラリが充実しているので、その気になれば結構良いWebフレームワークやテンプレートエンジンが作れるんじゃないかなと思います。

作ったプログラム(しょぼいので注意)

ひとまず、今回僕はGoを使って簡単なWebアプリを作ってみましたw

URLのパラメータにfrom, toを指定して、任意の範囲でグラフィカルなFizzBuzzができるアプリです。誰の役にもたちません(笑)

普通にやると

$ go run web.go

のようにして、localhost:4000にアクセスして動作を確認できますが、GCE上のDebian(つまり、このブログを動かしているインスタンス)でテストしていたので、4000ポートにアクセスできません。

curlならできますがつまらないですね。

susumuis@instance-4:~$ curl http://localhost:4000/?from=1&to=10
[1] 27781
susumuis@instance-4:~$ <!DOCTYPE html>
<html>
<head>
<title>hello, golang</title>

<style>
    .fizz { color: red; }
    .buzz { color: blue; }
    .fizzbuzz { size: 1.5rem; color: purple; font-weight: bold; }
</style>
</head>
<body>

to value must be integer
</body></html>

なので、一時的にこのブログを配信しているnginxに曲がりをしてインターネットに配信しちゃいましたwww「おまえ、いきなり本番環境に反映する気か!」などのツッコミには屈しません。(もう落としてます)

    location /goweb/ {
        proxy_pass   http://127.0.0.1:4000;
    }

golang - web - fizzbuzz

一応jQueryも入っているのでデバッガで画面いじるのが醍醐味ですw

Goの使いどころ

まだ事例は少ないですが、静的型付け・コンパイルというのがGoの最大の特長でしょう。それでいてpythonなどのライトウェイト言語の特長を取り込んでいるので、非常に良い言語だと思いました。次のような事例では有効でしょう。

  • インフラなどのリソースを極限まで活用したい
  • go言語がインストールされていない環境にアプリケーションを配布したい

ちなみに、

$ go build web.go

のようにしたらバイナリを出力できます。出力されたバイナリはgoがインストールされていない環境でも動作するようです。

susumuis@instance-4:~/godev$ go build web.go
susumuis@instance-4:~/godev$ ls -la | grep web
-rwxr-xr-x 1 susumuis susumuis 5703384  7月 27 21:42 web
-rw-r--r-- 1 susumuis susumuis    1466  7月 27 17:43 web.go

1.4KBのソースコードから吐き出されたバイナリは5.5MBですかwライブラリを含んでるのか大きいですね。フロッピーに入らない。

GoはWebがまだ弱いので、実質的に、静的型付けが欲しいWeb言語という用途ではまだでしょう。その用途ではFacebookが開発したHackが良いと思います。HackはPHPに型を載せたようなシロモノなので、普通にPHPのエコシステムが使えます。パフォーマンスはFacebookがHHVMを開発して頑張っています。さらに極限までチューニングしたい場合は素直にJavaを使うのが現状一番良いでしょう。ただし、Javaを使えば一律に速くなるというわけではなく、JVMという怪獣を手懐ける必要があります。

僕はその必要性を感じませんが、「サーバーもフロントも同じ言語を使いたい」という場合は、現状はNode一択なのでしょう。Dartがどこまで来るのか興味が湧いています。

実はこのブログを動かしているWordPressにHackで書いた独自プラグインを載せています。そんなことも簡単にできちゃいますが、それについては後日書きます。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1123 0
はてなブログからWordPressに移行するためにしたこと https://susumuishigami.github.io/susumuisinfo/entry/2014/how_to_move_from_hatena_to_wp https://susumuishigami.github.io/susumuisinfo/entry/2014/how_to_move_from_hatena_to_wp#respond Sat, 28 Jun 2014 16:32:04 +0000 http://www.susumuis.info/?p=973 ほっとくと忘れてしまいそうなので、忘れないうちに、記録残そうと思います。

はてなブログから、WordPressへ結構苦労して移行しました。その時やったことをざっと書きたいと思います。

記事の移行

はてなブログ用ツールで記事データの取得

定番ですが、下記のツールを利用しました。
はてなブログ用ツール

.NETで作られているのでWindowsかMonoの環境が必要です。MacもMono環境を整えればできるかもしれないと書いてましたが、Windowsマシン持ってきてやってしまいました。

はてなのAPIを使用しているらしいので、それなら、自分もAPI使ってもいいんですが、せっかくあるツールが使えるなら、やっぱ楽さには叶いません。

このツールでデータをエクスポートしたものは、完全ではありません。次の問題点があります。

  • コメントが含まれない
  • 画像などがはてなフォトライフのままである
  • シンタックスハイライトなどの装飾が一部崩れている

はてなダイアリーのエクスポート機能を使用

はてなブログにはエクスポート機能がありませんが、はてなダイアリーにはあります。はてなブログに移行する前ははてなダイアリーを使っていて、はてなダイアリー時代が大半だったので、はてなダイアリーにログインすることではてなダイアリー時代のデータを抜くことは出来ました。

方法は下記の記事と同じです。

はてなダイアリーからWordPressへ全記事を移行した件 | ツインズパパの徒然日記 Ver.2

上記記事にも書いてあるとおり、次の問題点があります。

  • はてなキーワードのリンクもそのまま持ってきてしまう
  • 一部の記事の日付が1970年になってしまう

    • →これは、時刻 00時代のAMがうまく取り込めないという問題。リンク先や、その方が参考にされたサイトでは01時に変更することで対処されていましたが、僕の場合はAM自体を取り除いたらうまくいきました。
  • シンタックスハイライトがガタガタ
  • 画像がはてなフォトラ(ry
  • なぜか一部の記事がうまく移行できないで画面が真っ白になった(すごい大昔の記事)

RSSからインポート

はてなブログはRSSも配信しています。そしてWordPressは公式でRSSからインポートすることができます。しかし、これは、.NETのツールの下位互換でした。

  • 新着7件しか取ってこれない
  • コメントデータを取ってこれない

結局どうしたか

  • はてなダイアリー時代の記事のうち、真っ白にならなかったものは、はてなダイアリーで移行
  • はてなブログ時代の記事ははてなブログで移行
  • はてなブログ時代のコメントは、3件しかなかったので手でSQLを発行して移行:
insert into
    wp_comments (
        comment_post_ID,
        comment_author,
        comment_author_url,
        comment_date,
        comment_date_gmt,
        comment_content,
        comment_karma,
        comment_approved,
        comment_parent,
        user_id

    ) values (
        614,
        'susumuis',
        'http://www.susumuis.info/',
        '2014-03-30',
        '2014-03-30',
        'id:faith_and_braveさん コメントありがとうございます。 共感いただいて本当に嬉しいです。 自分は開発(省略)',
        0, 1, 0, 1
    )

こんな感じです。コマンドラインツールでのSQLの発行はキツイし、phpMyAdminのような「クラックしてください」と言ってるようなツールは使いたくなかったので、このツールを使いました。SSHトンネルの設定もやってくれるので便利でした。

Sequel Pro

はてなキーワード持ってきてしまった件についてはSQLに正規表現書いて変換しようとしましたが、MySQLは正規表現を使った置換ができないそうなので、PHPなどの言語で外から変換するしかないようです。まだ出来ていませんので後日できたら報告します。

検索結果のindexとか「いいね」カウントとか

検索エンジンのインデックスについては、301リダイレクトで対処するのが王道ですが、これは、

はてなダイアリー → はてなブログ → 独自ドメイン(はてなブログPro)

を公式移行ツールで移行してきたのでシームレスにやってくれていました。なので、あとは、はてなブログProで使っていた独自ドメインのURLそのままで記事のURLを移行するだけです。

WordPressにはパーマリンク機能というのがあって、記事のURLを

http://www.example.jp/?p=123
のようにクエリーパラメータにするのではなく、
http://www.example.jp/2014/06/28/sample-post/
のような任意のURLにすることができます。

ここで、移行前のURLは次の形式になっていました。

はてなブログ時代

http://ドメイン/entry/yyyy/mm/dd/数字6桁
例:
http://www.susumuis.info/entry/2014/06/11/222935

はてなダイアリー時代

http://ドメイン/entry/yyyymmdd/p数字
http://ドメイン/entry/yyyymmdd/数字10桁
http://ドメイン/entry/yyyymmdd/任意の単語
例:
http://www.susumuis.info/entry/20110728/p1
http://www.susumuis.info/entry/20090822/1252377609

見事に分かれています。それなら、共通する、「/entry/2014」の部分 + 投稿名として「06/11/XXXXXX」を書くようにしようとしましたがこれはできません。

"/"という文字が投稿名に使用できなかったためです。

結局どうしたかというと、 Enhanced Custom Permalinksというプラグインのお世話になりました。これを使えば記事ごとにパーマリンクを設定できます。

さて、記事の数は90くらいありますので、全部手でやってたら大変ですから、こいつは、SQLで一括で設定してしまいました。

当時のクエリを残していなかったので、正確なものを紹介できませんが、wp_postmetaテーブルをinsertしていく形になります。

単なる301ではなく、URLを同一にしたため、はてなスター、Facebookいいねまでそのまま引き継ぐことが出来ました!

はてなブックマーク、はてブコメント

ところが、はてなブックマークについてはうまく行きませんでした。はてなブックマークもURLに紐づく情報なので、てっきりブログをそのまま移行すれば、独自ドメインでブックマークが引き継がれると思っていました。確かに移行直後はそうだったのですが、移行後数時間後、はてなブックマークカウントが0になっていました。

なんでかなあと思ってみたところ、はてなブログProの管理画面を見たら理由がわかりました。

独自ドメインは解除されている!

はてなブログは、定期的にドメインが有効かどうかクロールしているようです。ドメインがきちんとはてなのDNSに向いていることがわかった時点で、元のはてなブログのURLから独自ドメインのURLにリダイレクトしているようです。

ドメインが無効、または別のサーバーを向いていると判断されると、はてなブログのドメインから独自ドメインへの転送がストップします。それと同時に、はてなブックマークのデータも、元のはてなブログのドメインのものに変換され、独自ドメインのカウントは、0になります。はてなブログとして独自ドメインで受けたはてなブックマークカウントも、一緒にはてなブログドメインに持って行かれてしまいます。

はてなブックマークははてなのものだから仕方がないですね。

人気エントリー一覧

人気エントリーの一覧は、元のはてなブログドメインのものをはてなブックマークブログパーツを使用すれば作成できます。このままだとリンク先がはてなブログになってしまうので、リンク先をJavaScriptで強引に書き換えてしまいました。右サイドバーの「以前反響を頂いた記事」という部分です。具体的にはこんな感じです。

jQuery('div#hatena_hotentry').on('DOMNodeInserted', function() {
  $links = jQuery('div#hatena_hotentry .hatena-bookmark-entrytitle');
  $links.each(function() {
    jQuery(this).attr('href', jQuery(this).attr('href').replace('susumuis.hateblo.jp', 'www.susumuis.info'))
  });
});

こんなことして怒られたらやめます。wwもう、この段階で欲しいのは過去のはてなブックマークじゃなくて、この記事がオススメだよっていうことなので、僕の方で勝手にレコメンドしちゃえばいいんです。

ブックマークコメント

はてなブックマークコメントはどうしましょう。最近はブログのコメント機能を使ってのコメントより、はてなブックマークコメントで暑いコメントをもらったりします。

はてブコメントがないと、過去盛り上がった記事もなんか寂しい感じですね。ただ、個人的には、はてなブックマークに対しては歓迎的でない部分もあって、何かと炎上しやすいなど、攻撃的なこと書く人がたまにいます。

コメントなのか、個人のメモなのかわからないしろものですから、今後、ブログの雰囲気的を良くしていくためにはない方が良いかもしれません。

ということで、過去の記事まで追跡して、はてブコメントを画面に出すのはやめました。ただ、僕のブログのなかで、はてブ2桁頂いた記事が6件だけあったのでそれらについては記事の下に手動で旧ドメインでのブックマークリンクを記載しました。こんなかんじです。

この記事は以前多くのブックマーク・コメントを頂きました。
<a href="http://b.hatena.ne.jp/entry/http://susumuis.hateblo.jp/entry/20110728/p1" class="hatena-bookmark-button" data-hatena-bookmark-layout="simple-balloon" title="以前のURLでのブックマーク件数"></a>
これからブックマークされる方はこちら↓

Markdown記法を使えるようにする

WordPressにはMarkdownを使えるようにするプラグインが複数存在します。いろいろ試しましたが僕はこのプラグインが使いやすいと思いました。

WP Markdown Live

コードのインデントとシンタックスハイライト

はてなダイアリーやはてなブログから記事をインポートした結果、残念なこととして、ソースコードのインデントやシンタックスハイライトがガタガタになってしまったことがありました。

これについては、幸いWP Markdown LiveプラグインがGitHub風のプログラムコード記法を持っているので、テキスト化されたコードからもう一度自前でインデントしてMarkdownに貼り直すことにしました。全部だと大変だから一部だけです。

これだとシンタックスハイライトがつきませんがWP Markdown Liveで出力したコードは

<pre class=" language-css">
<code class=" language-css" data-language="css">

コード

</code>
</pre>

(*うまくコードをテキスト化してくれないので、最初のpだけ全角文字にしています)
のように出力されます。これはそのまま prism.jsが使用できます。

テーマのスタイルシートにダウンロードしてきたprism.cssとjsを配置するだけで、綺麗にシンタックスハイライトすることができました。

SEOとかOGPとかTwitter連携とか

まだまだやらなきゃいけないことはたくさんありますが、だんだん面倒くさくなってきてしまったので、これらはプラグインでお茶をにごしました。
余力があったらプラグインを使わずに自力で連携したいです。

使ったプラグイン
* Jetpack by WordPress.com
* WP Open Graph
* WP Social Bookmarking Light

Jetpack使ってるあたりが負けてる感がするので、早急に自力でなんとかしたいです。

SEOのメタタグの部分はしっくり来るプラグインが見つからなかったので自分でheader.phpにスクリプト書きました。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=973 0