AspireOneをSSDに換装
まあ今更?って感じのネタですね。しかもこんな古いマシンを今更?って感じですが、貴重な持ち運び可能なUbuntu端末としては非常に良い出来(Ubuntuと相性がよい)のでこのまま転がしておくのは勿体無い、ということでできるだけ安くあげました。
まあバラし方とかはググれば非常にわかりやすいサイトなどはいっぱいあるので、そっちを見てもらったほうがいいと思います。今回はなべラボさんの「acer Aspire OneのSSD換装とメモリ増設」を参考にさせて頂きました。ありがとうございます。
パーツ
- Plextor PX-64M2S
- SO-DIMM DDR2の1GBメモリ(バルク品でそのへんに転がってた奴)
7000円ちょいぐらいです。というか64GBSSDが7000円で買えちゃうとか、最近の値下がり率はハンパないですね。でも多分値段的にはもうこの辺が底かも?ってショップの自作オタ店員も言ってたので時期は悪くないかも。輸入したら円高でもっと安いかもですねぇ
難点
とにかくこのノート、バラしにくいです。というかHDDとメモリにアクセスするにはほぼ全部をバラしてマザーボードを引き摺り出さないといけないという、初心者泣かせです。しかもネジが多く、パーツの組み上げは結構雑というかかみ合わせが悪かったり無理矢理感があったりと、結構バラすだけでハラハラします。
TOPの画像を見てもらうとわかりますが、SSDに換装する為にはここまで出さないといけないんですよね…
Ubuntu
ま、なんとか換装して組み上げて再度UbuntuをInstallしました。11.10入れようかと思いましたがまだ正式リリースではないので11.04にしておきました。まあ10/13にはReleaseされる予定なので、その時には入れ替えちゃおうかなとも思ってますが。
使用感
さて、無事入れ替えてしばらく使ってみます…うん!早いね!明らかにディスクよりレスポンスいいです。まあCPUはatomなので、そもそもそんなに頭がイイ訳ではないですが、ディスクアクセスに関してはかなり改善されましたね。しかもHDDと比べて耐障害性はかなりアップしたのでこれからは気にせず持ち運べるのもイイ!
ただ気になるのはファイルシステムをext4でフォーマットしたのですが、そもそもext系はSSDに最適化されているか、と言われるとそうでもないですよね。HDDとSSDは似て非なるものですからねぇ。やはりbtrfsあたりにしとけばよかったかな。確かにbtrfsはSSD対応も含まれていたようないないような…
UbuntuでJDEEを自前でbuild
とりあえず今日のイライラ
- Emacsでjava書きたい
- JDEEを入れるが古くて腐ってた
- Emacs23だったらSVNのtrunkから持ってきたほうがいいお!と書いてある
- svnでcheckoutしてbuildしようとしたらantが必要だった
- ant入れたはいいが特定のtaskでコケる
- ant-contrib入れたけどうごかねー(からなんとかした)
- 動いたけどまたコケる
- 欲しいtaskがcontribに入ってない(ここでキレかけた)
- svnでcheckoutしたtaskを入れてbuildした←イマココ
とりあえず環境
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 10.04.3 LTS Release: 10.04 Codename: lucid $ emacs -version GNU Emacs 23.1.1 $ java -version java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9.9) (6b20-1.9.9-0ubuntu1~10.04.2) OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)
とりあえず流れ
まずJDKとかEmacsを入れます。UbuntuなのでpackageのEmacsとjdk入れてください。JDKはOpenJDKを入れてますがsun-javaでも多分大丈夫でしょう(未確認)。あとEmacs23は23.2からCEDETが標準装備されていますが、10.04(lucid)では23.1なのでこれもpackageから入れてください。
$ sudo aptitude install cedet-common cedet-contrib
11.04以降(natty)な人は多分Emacs23.2がdefaultになっているのでpackageにcedetは存在しません。なにせ標準ですから…あとelibも必要なので、これもpackageから入れます。
$ sudo aptitude install elib
これで準備完了
とりあえずant
antですが、これは1.8を入れました。lucidはdefaultでは1.7なので1.8用packageを入れてください。
$ aptitude search ant1.8 i ant1.8 p ant1.8-doc i A ant1.8-optional
で、これで万事うまくいく!…と思ったら甘かった
とりあえずcontrib
antでifやforのtaskを動かすにはant-contribが必須なのでinstallした訳ですが、このままでは何故か動きません。何故か?よくよく見てみるとantのclasspathであるはずの/usr/share/ant/libにant-contrib.jarが存在しません。ほぁ
$ ls -la total 12 drwxr-xr-x 2 root root 4096 2011-10-03 22:16 . drwxr-xr-x 5 root root 4096 2011-10-03 17:33 .. lrwxrwxrwx 1 root root 30 2011-10-03 17:33 ant-antlr.jar -> ../../java/ant-antlr-1.8.0.jar lrwxrwxrwx 1 root root 36 2011-10-03 17:33 ant-apache-bcel.jar -> ../../java/ant-apache-bcel-1.8.0.jar lrwxrwxrwx 1 root root 35 2011-10-03 17:33 ant-apache-bsf.jar -> ../../java/ant-apache-bsf-1.8.0.jar lrwxrwxrwx 1 root root 37 2011-10-03 17:33 ant-apache-log4j.jar -> ../../java/ant-apache-log4j-1.8.0.jar lrwxrwxrwx 1 root root 35 2011-10-03 17:33 ant-apache-oro.jar -> ../../java/ant-apache-oro-1.8.0.jar lrwxrwxrwx 1 root root 38 2011-10-03 17:33 ant-apache-regexp.jar -> ../../java/ant-apache-regexp-1.8.0.jar lrwxrwxrwx 1 root root 40 2011-10-03 17:33 ant-apache-resolver.jar -> ../../java/ant-apache-resolver-1.8.0.jar lrwxrwxrwx 1 root root 38 2011-10-03 17:33 ant-apache-xalan2.jar -> ../../java/ant-apache-xalan2-1.8.0.jar lrwxrwxrwx 1 root root 40 2011-10-03 17:33 ant-commons-logging.jar -> ../../java/ant-commons-logging-1.8.0.jar lrwxrwxrwx 1 root root 36 2011-10-03 17:33 ant-commons-net.jar -> ../../java/ant-commons-net-1.8.0.jar lrwxrwxrwx 1 root root 24 2011-10-03 17:33 ant.jar -> ../../java/ant-1.8.0.jar lrwxrwxrwx 1 root root 33 2011-10-03 17:33 ant-javamail.jar -> ../../java/ant-javamail-1.8.0.jar lrwxrwxrwx 1 root root 32 2011-10-03 17:33 ant-jdepend.jar -> ../../java/ant-jdepend-1.8.0.jar lrwxrwxrwx 1 root root 28 2011-10-03 17:33 ant-jmf.jar -> ../../java/ant-jmf-1.8.0.jar lrwxrwxrwx 1 root root 29 2011-10-03 17:33 ant-jsch.jar -> ../../java/ant-jsch-1.8.0.jar lrwxrwxrwx 1 root root 30 2011-10-03 17:33 ant-junit.jar -> ../../java/ant-junit-1.8.0.jar lrwxrwxrwx 1 root root 33 2011-10-03 17:33 ant-launcher.jar -> ../../java/ant-launcher-1.8.0.jar lrwxrwxrwx 1 root root 31 2011-10-03 17:33 ant-nodeps.jar -> ../../java/ant-nodeps-1.8.0.jar -rw-r--r-- 1 root root 2332 2010-04-10 01:43 ant-stylebook.jar lrwxrwxrwx 1 root root 22 2011-10-03 22:16 ant-svn.jar -> ../../java/ant-svn.jar lrwxrwxrwx 1 root root 30 2011-10-03 17:33 ant-swing.jar -> ../../java/ant-swing-1.8.0.jar lrwxrwxrwx 1 root root 29 2011-10-03 17:33 ant-trax.jar -> ../../java/ant-trax-1.8.0.jar
じゃあどこにあるのよ?という話ですがこれは他のリンクを見れば判りますが、/usr/share/javaに入ってます…うーん、よくわからんけど、入れるだけでいれでsym-linkすら貼ってくれないのはちょっと手抜きじゃないっすか!?と思ったわけですよ
$ ls -la | grep contrib -rw-r--r-- 1 root root 232180 2009-11-21 03:37 ant-contrib-1.0b3.jar lrwxrwxrwx 1 root root 21 2011-10-03 09:20 ant-contrib.jar -> ant-contrib-1.0b3.jar
なんで仕方ないので手でsym-linkを張ります
$ sudo ln -s ../../java/ant-contrib.jar ant-contrib.jar
これでant-contribが機能します。いや本当はclasspathをbuild.xmlに書いてもいいんですけど、いちいちめんどくさいしbuild.xmlには極力手を入れたくないというポリシー(?)ということにしておいてください。
とりあえずbuild
さて、これで万事準備が整った!JDEEのソースをcheckoutします
$ cd src $ svn co https://jdee.svn.sourceforge.net/svnroot/jdee/trunk jdee-trunk $ cd jdee-trunk/jdee $ ant configure <- build.propertiesを作成
build.propertiesを作成したら以下の箇所を編集します
cedet.dir=/usr/share/emacs/site-lisp/cedet-common <-cedetのホーム elib.dir=/usr/share/emacs/site-lisp/elib <-elibのホーム
それ以外はデフォでもokでしょう。変えたい人は適宜変更してください。んじゃまとりあえずbuildしてみます
$ ant build Buildfile: /home/misty/source/svn/jdee/trunk/jdee/build.xml init: prepare-lisp-build: configure: configure-ebuild: build-lisp: build-java: [javac] /home/misty/source/svn/jdee/trunk/jdee/build.xml: 162: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds build: BUILD SUCCESSFUL Total time: 0 seconds
お、いいっすね。次に行きます
$ ant bindist Buildfile: /home/misty/source/svn/jdee/trunk/jdee/build.xml init: prepare-lisp-build: configure: configure-ebuild: build-lisp: build-java: [javac] /home/misty/source/svn/jdee/trunk/jdee/build.xml: 162: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds build: bindist: BUILD SUCCESSFUL Total time: 1 second
はい、いいですね。なんかエラー出てますけどまあスルーで。じゃあpackageにして締めましょうか
$ ant package Buildfile: /home/misty/source/svn/jdee/trunk/jdee/build.xml <省略> BUILD FAILED /home/misty/source/svn/jdee/trunk/jdee/build.xml:210: Problem: failed to create task or type changelog Cause: The name is undefined. Action: Check the spelling. Action: Check that any custom tasks/types have been declared. Action: Check that any <presetdef>/<macrodef> declarations have taken place. Total time: 8 seconds
ギャース。changelogというtaskがねえよ!ボケが!ということですね。はて?なんでしょうね、このchangelog taskというのは
とりあえずantlib
実はこのchangelogというtaskは元々あるcvs用のtaskをsubversionのchangelog処理用のtaskとして使うラッパーライブラリのようです(本当?)実態はここにあります。このライブラリは、おまけ的な位置づけのようで、ubuntuのpackageには含まれていません(ここで時間使った(゚д゚)マズー)。まあ私はantはあまり使ったことが無いので「こんなの常識じゃん!」という話だったら聞かなかったことにしてください。
とりあえずこいつを入れないと全部すっきりbuildできないのでこいつを入れます。
$ svn co http://svn.apache.org/repos/asf/ant/antlibs/svn/trunk/ antlibs-svn $ cd antlibs-svn $ ant compile $ ant package <- jarファイルを作成する
さてこれでjarファイルができたので、所定の場所に突っ込んどきます
$ sudo cp build/lib/ant-svn-0.1-SNAPSHOT.jar /usr/share/java $ cd /usr/share/java $ sudo ln -s ant-svn-0.1-SNAPSHOT.jar ant-svn.jar
で、最後にantから見えるように
$ cd /usr/share/ant $ sudo ln -s ../../java/ant-svn.jar ant-svn.jar
これで完璧ですね。さっきのJDEEのソースディレクトリに戻ってbuildしてみましょう
$ ant package <省略> package: [tar] Building tar: /home/misty/source/svn/jdee/trunk/jdee/build/pkg/jdee-src-2.4.1.tar [zip] Building zip: /home/misty/source/svn/jdee/trunk/jdee/dist/pkg/jdee-src-2.4.1.zip [bzip2] Building: /home/misty/source/svn/jdee/trunk/jdee/dist/pkg/jdee-src-2.4.1.tar.bz2 [tar] Building tar: /home/misty/source/svn/jdee/trunk/jdee/build/pkg/jdee-bin-2.4.1.tar [zip] Building zip: /home/misty/source/svn/jdee/trunk/jdee/dist/pkg/jdee-bin-2.4.1.zip [bzip2] Building: /home/misty/source/svn/jdee/trunk/jdee/dist/pkg/jdee-bin-2.4.1.tar.bz2 BUILD SUCCESSFUL Total time: 29 seconds
はー、すっきり!あとはできたファイルで自前のEmacsに入れて設定してください。設定とかは検索すればいっぱい出てきます(無責任)
[android][ios]AndroidとiOSについてそろそろ以下略
とりあえず両方のOSも持っていますが、一応書いておきましょう
前置
XperiaはスマートフォンですがiPod touchはスマートフォンでは無いので、スマホとしての部分の評価は除きます
結論
いきなり結論からいうとですね、完成度としてはiOSが圧倒的でしょうね、これは。もちろんデバイス込みで見ると不満も多いです。自由は効かないしJBしないと好きに端末もいじれない(これはAndroid系も同じか…)
が、それを差し引いたとしてもiOSの完成度は圧倒的でしょう。じゃあそれは何か?
追従性
単純にタッチやスワイプに対する追従性です。これはもう文句のつけようがありません
両方触ったことある人ならわかると思いますが、iOS+Apple製ハード(まどろっこしいですがこう書きます)での指の動きに対する画面の追従性はハンパないです。どんな高性能Android端末でも勝ち目無いでしょう。一度店頭で触ってみてください。ミリ単位でもぴたっと指についてくる画面。でも慣性表示やスクロールの移動量など、視覚から人の感覚値に結びつく辺りの調整が非常に繊細にできてます。
初めての人が違和感なくぴたっとスクロールさせて目的の物を選べたり見たりできるのはこのへんの完成度の高さからでしょう。残念ですがAndroid端末でここまで違和感なく使える端末は見たことないし、いまの完成度を見ると多分ずっと無理でしょう。
このへんはOS+ハードで開発できる強みなので、Android単体での評価と結びつけるのはちょっとずるい気もしますが、当然と言えば当然ですね。
ここにこだわるのは当然理由があります。タッチパネルメインである以上、ヒューマンデバイスである指が唯一のInputです。これが正確に、確実に、迅速にOSに伝わらなければ意味がありません。ここの性能がダメダメじゃいくら高性能でも使う価値はゼロです。むしろゴミです。いや、むしろこの追従性だけでOSを選んでもいいと言っても過言ではありません。
事実、Android端末が出た当初ははっきり言って僕は全く相手にしてませんでした。カクカク動画すぎて。最近になってやっと「まあ我慢できるレベルかな」と思うぐらいです。
UI(というか、パーツ)
あと気になったのは、単純にUIのパーツが汚い、というか雑です、Androidは。Defaultの矢印ボタンみても、何時の時代のWebサイトだよ!って思うようなUIボタンです。センスもクソもありません。そりゃみんな独自にUIパーツ用意しますよ。んで見た目ばらばら使い勝手ばらばら…これはWindowsがかつて通った道ですね
Googleは最近になってようやく重い腰を上げてUIに関してガイドラインを引き始めそうな気配ですが、企業エゴと理想のオープン性は相容れないです。そこで割を食うのはユーザーだけというこれもいつか見た道。
Storeの質
AppStoreに対して「検閲なんてクソくらえ!」なんていう声もありましたが、蓋を開けたらAndroidMarketの方がクソだった、というワロエナイ話ですね。まあ単純にAppの質をみてもAndroidMarketは玉石混交というより、石が9割です。下手すると他人のAppをリネームして金とってる人もいるぐらいで、ゴミをゴミと見抜けない人が利用するのが難しいですね。
当然、AppStoreだって褒められたものではありません。制限キツすぎ、しかもその理由もよくわからなかったり、デバイスに対する制限がそのままAppにも反映されるので、やれることが狭い、という買った本人が「いったい誰のデバイスだよ!」と思わず叫びたくなるほどの管理社会です。そこに自由はありません。
とはいえ、その決められた枠の中はさすがジョブズ理想郷だけあって、高品質なのは否定できません。
というかですね、これは両方に当てはまる根本的な原因として日本人のレビューがクソすぎる慣れてないというのが今後の課題ですかね
それでもAndroidを選ぶ理由は何か?
単純な利用者から見ればAndroid端末を選ぶ理由は全くないと言っても過言ではないでしょう。それは現在、街中で見かけるiPhone利用者の数を見れば明らかです。「異常なほどに」iPhone利用者が多いです。札幌の地下鉄ですらiPhoneラッシュです。そんな中でXperia使ってると「なんだあの偽iPhonewwうぇww」って思われてるかと思うと死にたくなります。
それでも僕はAndroidスマホを選びました。そして1ヶ月使い続けてみて思いました。
…これはですね、ある種の調教なんですよ。ドSな人向け。デフォルトのまま使うとか、マジありえない。マゾい人は制限が多いiOSという囲われた似非理想郷(ディストピア)でいいんです。じゃじゃ馬を屈服させたくなるような、もしくは旧体制、保守的な安定に対するアヴァンギャルドさを求めるならAndroid以外に選択肢はありません。
Androidに安寧なる道はありません。あるのは目の前の積み上がるガラクタと、後ろには灰塵に帰した無数のゴミです。そういう意味では本質的な意味での理想郷、ゴミと破壊から生まれる理想こそユートピア。その積み上がるガラクタを如何に調教し、仕付けて、味付けして自分の物にするか。
「ねえ、instagram登録したから…キミにフォローしてほしいなぁ♪」
とか
「寂しいけど…Facetimeであえるねっ(キュルン」
とか言って女子力アップしてる子がいる中で、おもむろにノートPCとスマホをUSBでつなげてadb shellをいじってる、そんな刹那的な世界があってもいいじゃない。AndroidはそんなOSです
node.js + mongoose + mongodbで遊ぶ
NoSQLのmongodbは何がいいって、Javascriptととの親和性が高い。とりたてnode.jsで使うには最適と言っても良いんではないでしょうか。コマンドラインインターフェイスがモロにJavascriptというのもアツイです
$ mongo MongoDB shell version: 1.6.5 connecting to: test > show dbs admin local test blog > use blog switched to db blog > show collections modelskills posts syste,indexes > db.posts.drop() true > db.modelskills.find().forEach(printjson) ...
これだけでmongodbを選ぶ理由になります←
mongooseを入れる
さて、こいつをシェルから使うだけでもまあ面白いですが、折角node.jsでも遊んでるのでnode.jsからmongodbを使いたいと思います。今回はmongooseというmongodbに対してORM風にアクセスできるライブラリを利用します。導入にはnpmを利用しました。
$ npm install mongoose
必要なものは勝手に揃えていれてくれるのであまり気にしなくていいです。あ、えーと、このORM風なmongooseですが、ここ最近大きく改修が入りまして(というかバージョンアップ)、最近ネットでググると出てくるチュートリアル的なソースはほとんど使えません(ver 0.0.5辺りの物)
1.0.xになって大きく変わったと思う点が2つ
- Schemaの導入
- Middlewareの導入
でしょうか。
Schemaの使い方
mongooseのサイトにも簡単なモデルの定義例がありますが、Schemaとは要するにモデルの雛形的な物です。
var mongoose = require('mongoose'); // Default Schemaを取得 var Schema = mongoose.Schema; //配列に格納する埋め込みドキュメントのスキーマ定義 var CommentsSchema = new Schema({ title: String, body: String, date: Date }); // Defaultのスキーマから新しいスキーマを定義 var PostSchema = new Schema({ title: String, body: String, date: Date comments: [CommentsSchema], //配列もOK。ここにコメントモデルが格納される metadata: { votes: Number, favs: Number } }); // モデル化。model('[登録名]', '定義したスキーマクラス') mongoose.model('Post', PostSchema);
特に難しくは無いですね。とてもわかりやすいです。このスキーマ定義、fieldの定義だけならわざわざSchemaなんて仰々しい物を使う必要ありません。ここで先ほど書いた目玉の2つ目、middlewareが出てくるんですね
// PostSchema.pre('init', function(next) { //ドキュメント初期化時のフックとして処理したいこと console.log('init done'); next(); } PostSchema.pre('save', function(next) { //ドキュメント保存時にフックして処理したいこと console.log('save done'); next(); }
Schemaにpre-hookとして予めメソッドを指定して、必要な処理を記述すると、そのメソッドが実行されたときに自動的に処理されます。これはいろいろ使い道があるんじゃないでしょうか。なお、上に書いたのは同期的な記述で非同期でも可能です
PostSchema.pre('save', function(next, done) { //next()は即時実行されるが… otherFunc(done); next(); }
…と思いきやなんか非同期で動いていないような気がする。otherFunc()内でdone()を叩けばいいんですが?なんか使い方間違ってる?ここ、非同期の部分だけちょっとよくわかりません><w
Schemaには他にも仮想属性(Virtual Attribute)やField定義のカスタムオプションとかいろいろあるんですがまだ勉強ちゅー
カスタムオプションの例
var Person = new Schema({ title : { type: String, required: true } , age : { type: Number, min: 5, max: 20 } , meta : { likes : [String] , birth : { type: Date, default: Date.now } } });
使い方
さてSchemaを定義したはいいが、ようは使わないと意味がありません。新しいドキュメントを保存する場合は
//mongodb://[hostname]/[dbname] mongoose.connect('mongodb://localhost/blogdb'); //定義したときの登録名で呼び出し var Post = mongoose.model('Post'); var post = new Post(); //ドット表記で各Fieldへアクセス post.title = 'test title'; post.body = 'this is a pen'; //埋め込みドキュメントな配列にはpush()を使う post.comments.push({title: 'comment title', body: 'comment body'}); //pre-hookを定義しているとsave時に定義した関数が走る post.save(function(err) { if(!err) console.log('saved!') });
な感じです。モデルを使ってドキュメントを検索する場合は
//find()の第1引数にmongodbのQueryが入ります。 Post.find({title:/title/m}, function(err, docs) { if(!err) { for (var i = 0; i < docs.length; i++ ) { console.log(docs[i]); } } });
てな感じです。
基本的にはORM風なので、もっと手軽でもいいかなぁ、なんて思ってたりしますがこれはこれで非常に便利ではないでしょうか。
javascriptが楽しくなってきた系
久しぶりにこっちで日記
最近いろいろ新しい物に手を出してますが、その中で気になったのが
- node.js
- Google Closure Library
です。最近よく聞くとと思いますけど…
node.js
node.jsはサーバサイドjavascriptですね。話は簡単で、以下のようなソースを書いて「sample.js」というファイルで保存して…
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(8124, "127.0.0.1"); console.log('Server running at http://127.0.0.1:8124/');
コンソールから
$ node sample.js
てな感じに起動すると、上記の例だと8124ポートでlistenしてくれます。これでブラウザからアクセスすると文字列が出るわけですね。簡単です。
これはですね、なかなかいろいろな可能性を秘めてますよ。いまとてつもなく楽しいです、これ。最近Javascriptが重要視されてきてますが、サーバサイドはJavaだPythonだ、とどうしても多言語に依存せざるを得ない状況でした。
これは純粋にJavascriptだけでアプリが書ける、ということですね。
node.js
http://nodejs.org
Google Closure Library
こいつはですね、すごいですよ!←何が
要するにJavascriptライブラリなんですが、jQueryのようにAjax+DOM操作に加えて、いろいろなツールキットやユーティリティ、ネットワーク、イベント処理などなど、あらゆる機能を網羅した巨大ライブラリです。
ぶっちゃけこれを使えばもうjQueryのいいんだか悪いんだかわからないPluginを探しまくる日々から開放されます(言い過ぎか?w)
このLibraryは正確には
- Closure Library
- Closure Compiler
- Closure Template
の3つから構成されてます。Compilerは要はDeploy(公開)するときのJSファイルを最適化(難読化)してくれます。ClosureLibraryは開発時には利便性を考慮して非常に多くの分割されたJSファイルを読み込みます。
goog.require('goog.dom'); function sayHi() { var newHeader = goog.dom.createDom('h1', {'style': 'background-color:#EEE'}, 'Hello world!'); goog.dom.appendChild(document.body, newHeader); }
こんな感じにrequireで必要なものを読み込むんですが…まあjavaで言うところのimport文ですね。ただ、この1行でもブラウザで展開されるとJSファイルてんこ盛りでscriptタグに書きこまれます。依存関係がすごいですw
なので、そのまま手抜きしてClosureLibrary使うと重いです。マジで…
で、ようやくCompilerの話ですが、Compilerはrequireされる関連JSファイルから必要な部分だけを全部抜き出し、バイト数を削り、不要な改行や空白を削除して、1ファイルにしてくれるという凄い奴です。
Templateは…使ってないのでまだ知りません(笑)
てな感じで僕は現時点ではjQueryよりClosureLibraryに首ったけです
Titanium:メニュー系の項目作成
Titaniumではメニューの作成はAPIが用意されており、作成自体は非常に簡単に行えます。
ネイティブメニューの作成
アプリケーションのメニューに関してはまずcreateMenu()で大元のメニューコンポーネントを用意します。そこに子をぶら下げて行くイメージになります。
//メニューの作成 var menu1 = Titanium.UI.createMenu(); //メニューの親項目の作成 var item1 = Titanium.UI.createMenuItem("ファイル"); var item2 = Titanium.UI.createMenuItem("編集"); //メニューの子項目の作成 item1.addItem("終了", function(){ alert("selected: exit"); }); item2.addItem("設定", function(){ alert("selected: config"); }); //項目の登録 menu1.appendItem(item1); menu1.appendItem(item2); //メニューの登録 Titanium.UI.setMenu(menu1);
コンテキストメニュー
いわゆる右クリックで表示するコンテキストメニューも同じような要領で実装できます。
//コンテキストメニューの作成 //メニューの作成 var contextmenu1 = Titanium.UI.createMenu(); //項目の作成 var contitem1 = Titanium.UI.createMenuItem("コンテキスト1", function(){ alert("context1 clicked"); }); var contitem2 = Titanium.UI.createMenuItem("コンテキスト2", function(){ alert("context2 clicked"); }); //項目の登録 contextmenu1.appendItem(contitem1); contextmenu1.appendItem(contitem2); Titanium.UI.setContextMenu(contextmenu1);
実際にアプリケーションに実装する場合ではネイティブメニューは使いどころが難しい気がします。理由としては、MacOSXはデスクトップ上部にメニューが独立しているのに対して、Windows及びLinux系ではアプリケーションウィンドウ内にメニューがあるため、全体のレイアウトの差異をどこかで吸収しなくてはなりません。この差を細かく調整するぐらいならメニューなんてなくてもいいじゃない!という選択肢もありえる、ということですね。