ThinkPad W530 届きました
背景
今まで使ってた 15" MacBook Pro early 2011 が、AMD の discrete GPU が逝ってしまったのか、非常に調子が悪くなってました。
仕事で使ってるので、完全に死んでしまうといろいろとまずいので、新しいマシンを調達します。
機器選定
仕事柄、多数の VM を立ち上げる必要があるので、それに見合ったスペックが必要となります。そこで、いわゆるモバイルワークステーションが選択肢となります。
候補は MacBook Pro 15" Retina か ThinkPad W530.
当初は MacBook Pro Retina を考えてましたが、メモリとストレージがオンボード実装なので、これはちょっと NG. これで ThinkPad W530 を、ということになりました。
他社のはキーボードがテンキー付きだったり、やたらデカく重かったり。。
構成
- CPU: Core i7 3740QM (2.7GHz, 6MB)
- OS: Windows 8 Pro (64-bit) 日本語
- Display: 15.6 Full HD w/ カラーセンサー
- GPU: NVIDIA Quadro K1000M 2GB
- RAM: 16GB PC3-12800 DDR3 2 slot
- Keyboard: US w/ back light
- Storage: 256GB SSD
- 指紋センサー
- Bluetooth 4.0, Intel Centrino Ultimate-N 6300
- Office Home and Business 2013
- 3 年間オンサイト修理 and アクシデント・ダメージ・プロテクション
しめて \358,229 ですが、これに期間限定クーポンの 25% 引きをきかせて、
\276,539
でした。割引額だけでウルトラブック買えちゃいます。
おもしろそうなのでキャリブレータも付けてみました。Lightroom で RAW 現像したりするので、役に立つかな、と。
メモリスロットは 4slot 搭載、オーダー時実装 2slot 16GB なので、8GB のモジュール 2 枚買ってきて取り付ければ 32GB にも UG 可能な感じですかね。
到着まで
オーダー時の見積もりは、9 営業日発送、+4 営業日お届けだったので、予定よりも早く届いた感じですね。
軽くレビュー
一番懸念してたのがキーボード。まぁ Web 上ではいろいろな批評がありましたが、個人的には全然問題ないです。MBP よりも遙かにいいキーボードが搭載されています。
ディスプレイも鮮やかでいいですね。
このレビュー書いてる時点ではもう Haswell, 3k ディスプレイな W540 が発表されてますが、8 万近い値引き、今までの流れをある程度汲んだ筐体、非テンキー搭載、ということで特に失敗した感はないかなーと (言い訳
3 年オンサイト保証も付けたので、しばらくはこいつをメインにしていく感じです
MBP 修理いくらかかるかな。。。
MacRuby で Pasteboard 監視・HTML スクレイピング・WebView 操作
どういうのを作るか
英文のリソースを読んでいる最中、わからない単語が出てきたらオンラインの Cobuild (ここ) で検索してるんだけど、いちいちキーボード叩いたり、コピペするのはめんどくさい。
これを、Pasteboard を監視し、単語がコピーされたら自動でその単語の意味を表示出来たら難しい英文読むときに捗るかなと思い、ツールを作ってみることに。
どうやら、さくっと OS X の GUI アプリを書きたい時に MacRuby がなかなかよいらしいので、これでちょっと組んでみる。OS X のバージョンは 10.7
MacRuby のインストール法、プロジェクトの作成は省略。
WebKit.framework の追加
WebView を使うには、WebKit.framework が必要になるので、これへのリンクを張る。
アクセサの準備
WebView と連携するためでもある、アクセサを準備。AppDelegate.rb にはもう既に attr_accessor :window
と記述されてるので、同じように attr_accessor :browser
とかしてアクセサを準備する。
WebView 配置、アウトレット接続
こんな感じに InterfaceBuilder でさくっと WebView を配置。
後は左ペインの "AppDelegate" から "WebView" へ右クリックしながらドラッグするなどして、先ほど追加したアクセサに接続。
Pasteboard 監視
OS X での Pasteboard は、コピーした瞬間に通知を受け取れるような API がなさそうなので、ポーリングをかけるとする。AppDelegate.rb にこんな感じで Pasteboard を監視するコードを書く。
def applicationDidFinishLaunching(a_notification) beginObservingPasteboard end def beginObservingPasteboard @changeCount = NSPasteboard.generalPasteboard.changeCount NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector:"observePasteboard:", userInfo:nil, repeats:true) end def observePasteboard(timer) pboard = NSPasteboard.generalPasteboard if pboard.changeCount > @changeCount then pasteboardChanged pboard end @changeCount = pboard.changeCount; end def pasteboardChanged(pboard) classes = [ NSString ] objects = pboard.readObjectsForClasses(classes, options:nil) copied_str = objects[0] openURL("http://dictionary.reverso.net/english-cobuild/#{copied_str}"); end
beginObservingPasteboard
メソッドで、タイマを登録。selector はただ単にメソッド名の文字列を渡せばよい模様。そして observePasteboard
でクリップボードのアイテムが増えたか判定、増えてたら (= コピーされたら) pasteboardChange
を call, コピーされた文字列を取り出して、Web サイトアクセス開始する。openURL
については後述
HTML スクレイピング
ただ単に Web サイトを表示するだけならここまでで OK だが、上述のサイトは不要な部分が多いので、ごにょごにょすることにする。
XML パーサでいろいろとやるのもいいけど、WebView に一旦コンテンツを読み込ませてから、内部の DOM ツリーを操作できるようなので、このアプローチでいくことに。
まずは HTML を読み込ませる、非表示の WebView を作成。AppDelegate の applicationDidFinishLaunching
で作ってインスタンス変数にでも格納しておく。
@domParser = WebView.new webFrameLoadDelegate = WebFrameLoadDelegate.new webFrameLoadDelegate.browser = self.browser @domParser.setFrameLoadDelegate(webFrameLoadDelegate)
この domParser には、フレームのロード完了通知を受け取るため、WebFrameLoadDelegate を登録する。この WebFrameLoadDelegate クラスは、外部のファイルに切り出している。WebFrameLoadDelegate には、結果表示も任せたいため、browser への参照を渡しておく。
前述の openURL
メソッドで、HTML コンテンツのロードを開始する。
url = NSURL.URLWithString(url) urlRequest = NSURLRequest.requestWithURL url @domParser.mainFrame.loadRequest(urlRequest)
フレームのロードが完了すると、Objective-C の場合は、webView:didFinishLoadForFrame:
が呼ばれるらしい。Obj-C ではこれに対応するため、プロトコルを導入して〜とかしなければならなかったが、MacRuby では Ruby の動的性を生かして、ただ単に def webView(sender, didFinishLoadForFrame:frame)
というようなメソッドを定義するだけでよいみたい。らくちん。
以下 didFinishLoadForFrame の中身
document = frame.DOMDocument htmlDivElement = document.getElementById("DivMainResults") if (htmlDivElement != nil) then html = "<!doctype html><html><head></head><body>#{htmlDivElement.innerHTML}</body></html>" mainFrame = browser.mainFrame mainFrame.loadHTMLString(html, baseURL:NSURL.URLWithString("/")) end
ここまで来ると、あとは WebView の Frame から、DOMDocument が取得してこれるので、こいつで欲しい部分 (ここでは "DivMainResults" を id にもつ部分ツリー) を取得し、適当なコンテナ HTML に流し込み、結果表示先の WebView (ここでは browser 変数) に読み込ませる。
以上で、クリップボードを監視し、コピーされた単語を Web サイトにリクエストし、結果から必要な部分を取り出し表示する、ということが出来るようになった。ちなみにスクリーンショット:
おわりに
Ruby で書けるようになっているとはいえ、Objective-C のシンタックスを置き換えたような感じなので、Cocoa などの知識が必要になる。また、MacRuby のドキュメントもあまり充実しているとは言えないため、Apple 本家の Objective-C ドキュメントを読む必要があり、Cocoa Objective-C プログラミングしたことないような人には若干ハードル高いかなーと感じた。ただ、本ツールでは 60 行ほどしかコード書いてないので、経験のあるような人は楽に GUI アプリ書けるだろうなーとか思いました。
iOS5 で MPMoviePlayer を使ってみる
iOS5 での音声、動画の再生が一番楽だと思われる MPMoviePlayer を使ってみる。サンプルとしては Apple で提供されている HTTP Live Streaming サンプルを使用。
MPMoviePlayerController を使うときは、Xcode で MediaPlayer.framework を使えるようにし、
#import <MediaPlayer/MediaPlayer.h>
としてインポートしてくる。
コード:
NSURL* url = [[NSURL alloc] initWithString:@"http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8"]; _player = [[MPMoviePlayerController alloc] initWithContentURL: url]; _player.view.frame = self.view.bounds; [self.view addSubview:_player.view]; [_playerprepareToPlay]; [_player play];
_player は property として宣言