MacRuby / Ruby 1.9.0 のObjective-C実装
去年の12/25にリリースされたRuby 1.9.0ですが、Mac上で動作するRuby 1.9.0 の実装が公開されていました。
Objective-Cで実装されているので、それなりに実行速度は速そうです。
気になるのは、本家との互換性、MacPortsでインストールしている1.8.6と同居可能かというところです。
早くMacPortsで配布してほしいところです。
ようやく、主要なプラットホームで動作するようになってきたので、Mac 上で 1.9.x系を検証する場合に合わせて使ってみますか。
Ext Scaffold Generator Pluginを使う
管理機能などのCRUD画面で使用できるscaffoldジェネレータを探していたところ、extjsを使用したscaffoldジェネレータを見つけました。
http://inside.glnetworks.de/2008/01/18/announcing-ext-scaffold-generator-plugin-for-rails/
以下は、検証した記録です。
インストール
Ext Scaffold Generator Pluginは、Rails Version 2.0 以上が必要です。
1.2.x以前のバージョンの場合、予め、gem update railsを実行します。
- ext-2の配布ファイル(2008/02/27時点最新版:ext-2.0.1.zip)をダウンロード:http://extjs.com/deploy/ext-2.0.1.zip
- $rails_app/public/配下にextディレクトリ作成。
- ダウンロードしたext-2.0.1.zipを作成したextディレクトリに展開。
- $rails_appディレクトリでscript/pluginを実行します。
$ script/plugin install http://rug-b.rubyforge.org/svn/ext_scaffold
以上でインストール完了です。
ext_scaffoldジェネレータを使う
空のMVCを作成する
"script/generate ext_scaffold ModelName"を実行すると、モデルのMVC作成されます。
$ script/generate ext_scaffold Hoge exists app/models/ exists app/controllers/ exists app/helpers/ create app/views/hoges exists app/views/layouts/ exists test/functional/ exists test/unit/ exists public/images/ext_scaffold create app/views/hoges/index.html.erb create app/views/hoges/show.html.erb create app/views/hoges/new.html.erb create app/views/hoges/edit.html.erb create app/views/hoges/_form_items.html.erb create app/views/layouts/hoges.html.erb dependency model exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/hoge.rb create test/unit/hoge_test.rb create test/fixtures/hoges.yml exists db/migrate create db/migrate/001_create_hoges.rb create app/controllers/hoges_controller.rb create test/functional/hoges_controller_test.rb create app/helpers/hoges_helper.rb route map.resources :hoges
通常のscaffoldジェネレータと違い、modelも作成されます。
CRUD用viewファイルは作成されますが、モデルのフィールド定義がないため、Newアクションを実行しても新規作成画面は何も表示できません。
Viewの一覧もID列しか表示されないようです。
このため、一覧の列定義、入力フィールド等は、"app/views/hoges/index.html.erb"、"app/views/hoges/_form_items.html.erb"に記述します。
一覧の列項目/入力項目を指定してext_scaffoldを実行する
「空のMVCを作成する」で実行した場合、一覧の列項目や入力項目が追加されないため、そのまま管理画面で使用できません。
管理画面で使える様にするためにext_scaffoldジェネレータ実行時に表示/編集する項目を設定します。
+ 書式: script/generate ext_scaffold User field_name:データ型[, field_name:データ型, ...]
"script/generate ext_scaffold DataModel name:string"様にに実行すると、一覧にID列とName列が表示され、新規作成画面では、Nameを入力できる様になります。以下は、Fugaモデルに、nameカラムを追加してext_scaffoldを実行しています。
$ script/generate ext_scaffold Fuga name:string exists app/models/ exists app/controllers/ exists app/helpers/ create app/views/fugas exists app/views/layouts/ exists test/functional/ exists test/unit/ exists public/images/ext_scaffold create app/views/fugas/index.html.erb create app/views/fugas/show.html.erb create app/views/fugas/new.html.erb create app/views/fugas/edit.html.erb create app/views/fugas/_form_items.html.erb create app/views/layouts/fugas.html.erb dependency model exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/fuga.rb create test/unit/fuga_test.rb create test/fixtures/fugas.yml exists db/migrate create db/migrate/002_create_fugas.rb create app/controllers/fugas_controller.rb create test/functional/fugas_controller_test.rb create app/helpers/fugas_helper.rb route map.resources :fugas
この処理で"db/migrate/002_create_fugas.rb"に:nameカラムが追加されます。
ただし、現在のバージョンでは、データ型定義以外の制約は設定できなため、必要な制約は、migrateファイルに記述します。
ext_scaffoldジェネレータを実行後、"rake db:migrate"を実行します。。
$ rake db:migrate (in /Users/maxy/repos/rails_sandbox) == 3 CreateFugas: migrating =================================================== -- create_table(:fugas) -> 0.0027s == 3 CreateFugas: migrated (0.0030s) == ========================================
rake実行後、サーバを起動します。http://localhost:3000/fugas/へアセスすると、ID/Nameカラムが表示されます。
Newボタンクリックすると新規作成画面が表示されます。Nameの入力が行えます。
日本語による入力も問題ないようです。
Editボタンをクリックすると、編集画面が表示されます。
また、Deleteボタンによる選択行の削除、Search欄からの検索なども実行できます。
気がついた点
Ext Scaffold Generator Pluginは、まだ公開された直後らしく安定した動作をしていない点がみられました。
- モデルが存在する状態でgenerateを実行すると、Controllerが作成できない。
- script/generate ext_scaffold 実行時にmodelのカラムを指定した場合に、指定したデータ型で作成されない場合がある。
今回は時間が無かったため、各問題の解決方法まで調査できませんでした。
時間があるときに調査してみたいです。
ps. Dojoベースのscaffoldジェネレータとかあると便利そう。作ってみるか...
はてなダイアリーを試す。
はてな記法でソースコードの表示ができるようなので、試してみました。
Rubyのコードを貼り付け
出展:http://jp.rubyist.net/magazine/?0005-RubyOnRails
まずは、ActionControllerのクラスから
require File.dirname(__FILE__) + '/../test_helper' require 'debate_controller' # Re-raise errors caught by the controller. class DebateController; def rescue_action(e) raise e end; end class DebateControllerTest < Test::Unit::TestCase def setup @controller = DebateController.new @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new end # Replace this with your real tests. def test_truth assert true end end
次は、YAML
development: adapter: mysql database: rails_development host: localhost username: root password: test: adapter: mysql database: rails_test host: localhost username: root password: production: adapter: mysql database: rails_production host: localhost username: root password:
Javascript
出展:http://extjs.com/deploy/dev/examples/grid/array-grid.js
/* * Ext JS Library 2.0.1 * Copyright(c) 2006-2008, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ Ext.onReady(function(){ Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); var myData = [ ['3m Co',71.72,0.02,0.03,'9/1 12:00am'], ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'], ['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'], ['American Express Company',52.55,0.01,0.02,'9/1 12:00am'], ['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'], ['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'], ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'], ['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'], ['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'], ['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'], ['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'], ['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'], ['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'], ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'], ['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'], ['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'], ['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'], ['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'], ['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'], ['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'], ['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'], ['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'], ['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'], ['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'], ['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'], ['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'], ['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'], ['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'], ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am'] ]; // example of custom renderer function function change(val){ if(val > 0){ return '<span style="color:green;">' + val + '</span>'; }else if(val < 0){ return '<span style="color:red;">' + val + '</span>'; } return val; } // example of custom renderer function function pctChange(val){ if(val > 0){ return '<span style="color:green;">' + val + '%</span>'; }else if(val < 0){ return '<span style="color:red;">' + val + '%</span>'; } return val; } // create the data store var store = new Ext.data.SimpleStore({ fields: [ {name: 'company'}, {name: 'price', type: 'float'}, {name: 'change', type: 'float'}, {name: 'pctChange', type: 'float'}, {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'} ] }); store.loadData(myData); // create the Grid var grid = new Ext.grid.GridPanel({ store: store, columns: [ {id:'company',header: "Company", width: 160, sortable: true, dataIndex: 'company'}, {header: "Price", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'}, {header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change'}, {header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'}, {header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'} ], stripeRows: true, autoExpandColumn: 'company', height:350, width:600, title:'Array Grid' }); grid.render('grid-example'); grid.getSelectionModel().selectFirstRow(); });
Ubuntu 7.04から7.10へ移行。
もう2、3ヶ月で8.xが出そうな頃ですが、ようやく7.04から7.10へバージョンアップしました。
インストール先メディアがUSBメモリ/4GBと容量が限られているため、通常のアップデート手順では容量不足のために早々に断念。データ移行を行うことにしました.
必要なデータのバックアップを取ってUSBメモリに新規にインストール、その後データパーティションにバックアップを復元して移行完了しました。
参考:Desktop CD をUSBメモリにインストールする方法
今回はUSBメモリのパーティションを変更しなかったため、上記ページの手順のうち、「5. fdiskコマンドでパーティションを切る。」手順は省略しました。
バージョンアップ後、アップデートマネージャーでシステムを更新すると、'cupsys: サブプロセス post-installation script はエラー終了ステータス 127 を返しました'のエラーが発生しました。
ググると7.10からAppArmorなるセキュリティ層が導入され、cupsがエラーを起こすとのこと。
参考:Ubuntu 7.10 リリースノート その他の既知の問題 - AppArmorと印刷
以下のコマンドを実行して解決しました。
$ sudo aa-complain cupsd
その後、アップデートマネージャでシステム更新。今度は問題なく更新されました。
apt-get で必要なパッケージをインストールしてアップデート作業終了。
上記手順、アップデートというよりデータ移行なのですが、容量の少ないUSBメモリでバージョンアップする際には有効な方法でしょう。
ということで、Hello Ubuntu 7.10!
ubuntu 7.10にmecab 0.97をインストール
ubuntu 7.10にmecab 0.97とIPA辞書をソースビルドを行いインストールした手順です。
配布元のインストールガイド UNIX項を参考にインストールしました。
参考:MeCab: Yet Another Part-of-Speech and Morphological Analyzer#インストール
1. 必要なパッケージのインストール
ubuntu 7.10をUSBメモリにインストール直後の開発用パッケージをほとんどインストールしていない環境にmecabをインストールしています。
この環境では、makeを実行した時にエラーが発生します。
あらかじめ、gawkとbuild-essentialの2つのパッケージをインストールします。
$ sudo apt-get install gawk
$ sudo apt-get install build-essential
2. mecab 0.97インストール
ubuntuの日本語環境がUTF-8のため、キャラクタセットを'utf-8'でインストールします。
$ wget http://jaist.dl.sourceforge.net/sourceforge/mecab/mecab-0.97.tar.gz
$ tar -xzf mecab-0.97.tar.gz
$ cd mecab-0.97
$ ./configure --with-charset=utf8
$ make
$ make check
$ sudo make install
3. IPA 辞書インストール
$ wget http://jaist.dl.sourceforge.net/sourceforge/mecab/mecab-ipadic-2.7.0-20070801.tar.gz
$ tar -xzf mecab-ipadic-2.7.0-20070801.tar.gz
$ cd mecab-ipadic-2.7.0-20070801/
$ make
$ sudo make install
4. /etc/ld.so.confファイルの編集
mecabをインストールした状態では、'libmecab.so.1'が見つからない旨のエラーが発生します。
$ mecab
mecab: error while loading shared libraries: libmecab.so.1: cannot open shared object file: No such file or directory
'libmecab.so.1'は、'/usr/local/lib/libmecab.so.1'にインストールされていますが、ubuntu標準の設定では、'/usr/local/lib/'配下のライブラリが読み込まれないようです。
そこで、'/etc/ld.co.conf'ファイルに'/usr/local/lib'を追加し、ライブラリを読み込まれるようにします.
$ sudo vi /etc/ld.so.conf
/usr/local/lib # この一行を追加
追加後、ldconfigを実行して、ライブラリ読み込みパスを更新します。
$ sudo ldconfig
MacPortsを使ったRuby/Railsのインストール
MacPortsを使ったRubyとRuby on Railsのインストール記録です。
Rubyをインストールする場合、Ruby本家からソースコードをダウンロードしてコンパイルする方法が開発者らしいと思ったのですが、自宅Macなので時間をかけたくなかったため、安直な方法を選びました。
MacPortsのインストールとRuby本体、RubyGems、Ruby on Railsをインストールすることを目指します。
MacPortsのインストール
MacPortsのインストールははこべにっき#さんの「MacPortsでステキなUNIXツールをインストール」を参考にさせていただきました。
MacPortインストールの準備
MacPortsのインストールにはXcode Toolsが必要です。
Xcode Toolsは、Max OS X付属のインストールディスクを使用してインストールするか、Apple Developper Connectionのサイトからダウンロード(要会員登録)してインストールします。2007/09/02現在、Xcodeの最新版は、2.4.1です。
Rubyのインストール
MacPortsのインストールが終了したら、本題のRubyとRailsのインストールを行います。
まずは、Ruby本体のインストールから。
MacPortsは、通常依存関係があるソフトウェアやライブラリがあわせてインストールされるため、下記コマンドだけでRubyのインストールが実行されます。とっても簡単。
$ sudo port install ruby
MacPortsのインストーラはソフトウェアをインストールする際にソースコードのダウンロード、コンパイル、インストールを行っているようなので、Rubyの様な多くのライブラリに依存しているソフトウェアのインストールには時間がかかります。
インストール実行中のログを眺めていると、Rubyが必要としているライブラリが見えてきてちょっとしたお勉強になりますね。
インストール終了後、"ruby -v"を実行すると、バージョン情報が表示されます。
$ ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin8.10.1]
「ruby 1.8.6」と表示されれば、ちゃんとインストールがされています。
Rubyのバージョンが「ruby 1.8.6 (2007-03-13 patchlevel 0) 」ということなので、Ruby本家の最新版(1.8.6-p36)からすると少し古いバージョンがインストールされています。