2012年11月14日水曜日

17日目:Ruby勉強終了

Rubyも随分読めるようになったので、Rubyの勉強は終了です。
何か、作ってみましょうか。

2012年11月13日火曜日

16日目:Net::HTTP、超便利。

今日は軽めに。

require("net/http")
Net::HTTP.start("google.com") do |http|
  response = http.get("/")
  p response.body
end

他サービスアクセス、超楽ね。
さてそろそろRubyを使って何かアプリケーション作ろうかな。
勉強は一段落で、実践に入っていきます。


2012年11月12日月曜日

15日目:テストコードを見てみる。

Rubyと言えばTDDでしょ!(?)
ということで、今日は先日作成したRailsのScaffoldで作ったテストコードを見てみます。
test/functional/users_controller_test.rb
中を見ると、最初のメソッドはこんな感じ

  setup do
    @user = users(:one)
  end

setupはJUnitのsetupと一緒なんでしょう。ですが、ん?なに「:one」って?
調べたところ、これは
test/fixtures/users.yml
の中に用意されているテストデータを読み取ってるそうです。便利。
次のメソッドは以下、

  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:users)
  end

テストに説明(=should get index)を付けて、テストを実行しています。
indexにGetアクセスをして、レスポンスがsuccess(=200?)であることを確認しています。

assert_not_nil assigns(:users)
は、viewで、@usersがnullでないことを確認しているものです。例えば、controllerで@users変数に値を入れていることをテストしています。

その後にもたくさんのテストメソッドがありますね。

テストも簡単に書けるんですね。便利。


2012年11月11日日曜日

14日目:テスト、大事!

RailsのScaffoldを実行するとテストコードも一緒に出力されます。
Only in app2/Ins/test/fixtures: users.yml
Only in app2/Ins/test/functional: users_controller_test.rb
Only in app2/Ins/test/unit: helpers
Only in app2/Ins/test/unit: user_test.rb
今日はこのテストを勉強します。
users_controller_test.rbは「機能テスト」と言われるコードだそうです。
対して、user_test.rbは「単体テスト」と言われるコードだそうです。

まずはテストを実行します。
jruby test/functional/users_controller_test.rb 
LoadError: no such file to load -- test_helper
  require at org/jruby/RubyKernel.java:1019
  require at /Applications/jruby-1.7.0/lib/ruby/shared/rubygems/custom_require.rb:36
   (root) at test/functional/users_controller_test.rb:1

怒られる。。。調べてみると、-Itestパラメータをつけるらしい。
jruby -Itest test/functional/users_controller_test.rb 
Run options: 
# Running tests:
EEEEEEE
Finished tests in 0.243000s, 28.8066 tests/s, 0.0000 assertions/s.
  1) Error:
test_should_create_user(UsersControllerTest):
ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: query does not return ResultSet: PRAGMA table_info("users")
・・・・
一歩前進!しかしながら、テストがダメだって言われる。dbがないらしい。マイグレートしていないからか。
rake RAILS_ENV=test db:migrate 
jruby -Itest test/functional/users_controller_test.rb 
Run options: 
# Running tests:
.......
Finished tests in 0.915000s, 7.6503 tests/s, 10.9290 assertions/s.
7 tests, 10 assertions, 0 failures, 0 errors, 0 skips

成功!
今日はここまで、次回はテストコードを読んでいきます。

2012年11月10日土曜日

13日目:Viewを見る。

先日作った、Rails Scaffoldでできたものを確認してます。
今日はViewを確認します。
 ls app/view/users 
 _form.html.erb edit.html.erb index.html.erb new.html.erb show.html.erb 
erbとはembedded Rubyの略で、JSPみたいにファイルをかけます。

JSPと同じく、
<% %>
の中にRubyスクリプトを書けて、
<%= %>
で、値を出力できます。

便利そうなのが、Railsがerb中にかけるように用意しているビューヘルパーというメソッドたちです。
例えば、index.html.erbに書かれている
<%= link_to 'Show', user %>
は、link_toというビューヘルパーを使っていて、ブラウザには以下のように出力されます。
<a href="/users/2">Show</a>
htmlを出力する処理は、Railsに必要なビューヘルパーが用意されていないかを確認しながら実装したほうがよさそうですね。
ビューヘルパーは自分で作ることもできるので、綺麗に実装できそうです。
でも、記法はEL式のほうがエレガントかな。

erbファイルはコントローラで出力するerbファイルを指定できますが、指定しない場合は
view/コントローラ名/メソッド名.html.erb
が呼ばれます。

Railsではレイアウトファイルが用意されていて、デフォルトではすべてのerbファイルは
app/view/layouts/application.html.erb
に組み込まれてブラウザに出力されます。

_が頭につくerbファイルは部分ビューで、他のerbファイルに組み込まれます。_form.html.erbはnew.html.erbの
<%= render 'form' %>
で読み込まれています。

ビューヘルパー、素敵そう。

2012年11月9日金曜日

脇道にそれて。Xperia AXとVLの違い

ちょっと脇道にそれて、Xperia AXとVLのデザイン上の違いをご紹介。
Xperia AX/VLは、海外ではXperia Vと呼ばれるAndroidの日本バージョンで、AXはdocomo、VLはauから出ています。
同じXperia Vの日本バージョンなんですが、中に乗っているソフトウェアだけでなく、外見上もデザインが違います。
で、私見。

auのXperia VLのほうが、断然カッコいい。

ちょっとした違いなのに、かっこ良さは段違いです。
大きな違いを二点。
①AXには、ディスプレイ上部に要らないdocomo Xiロゴがある。VLはスッキリ。
AXは、docomoの広告をいつも見ながらスマフォを操作してるようなものです。あくまで私見ですが、あまり気持ちのいいものじゃないなぁ。
対してVLは、すっきりした見た目。とてもいいです!

②AXは下のほうに変なでっぱり。VLはスッキリ。
AXはカクカクっておしりが出っ張ってます。
VLは本体の長さ自体は変わらないんですが、でっぱりが斜めにカットされてて、スッキリ。

完全に私見、主観ではありますが、買うならXperia VLですねー。




12日目:動いてなかったScaffold

9日めの勉強で、
ActionView::Template::Error (application.css isn't precompiled):
というエラーが出た時の対応が間違っていたので、やり直し。
このエラーはcssとjavaScriptが生成されていないこと。
対応は二種類の方法があります。いずれかをすれば良いですが、②がおすすめ。
①動的に生成されるように設定
②予め生成(プリコンパイル、プレコンパイル?)しておく。


①動的に生成されるように設定
config/environments/production.rb
のL18行目あたりの以下の行を修正
  # ↓ config.assets.compile = false
  config.assets.compile = true

②予め生成しておく。
アプリケーションのルートで以下のコマンドを実行します。
bundle exec rake precompile RAILS_ENV=production

これでScaffoldで作られたアプリが動くようになります。

んー。難しい。

2012年11月8日木曜日

11日目:引き続きscaffoldからRailsを理解する。

昨日からScaffoldをつかってRuby on Railsを勉強しています。
今日はModelを見てみます。
app/models/user.rb


class User < ActiveRecord::Base
  attr_accessible :introduction, :name, :tel
end

シ、シンプル。
ActiveRecord::Baseクラスが強力なんだろうとrailsのサイトで調べてみました。
すごいたくさんメソッドがある。
今日はさらっと終わります。



2012年11月7日水曜日

10日目:scaffoldって何やってるの?を通してRailsを学ぶ。

Rubyを勉強し始めてもう10日めになります。早いものです。
今日はRailsを勉強するために、Scaffoldコマンドで何が作られているか見てみます。

Scaffoldで何が作られているかを見るために同じ名前のアプリケーションを作って、両者を比較してみます。

 mkdir app1 
 mkdir app2 
 rails new app1/Ins 
 rails new app2/Ins 
Insという名前のRailsアプリが2つ作られました。差分をとってみます。
diff -r app1/Ins/ app2/Ins/

diff -r app1/Ins/config/initializers/secret_token.rb app2/Ins/config/initializers/secret_token.rb
< Ins::Application.config.secret_token = '48c1a18ac89c1f36559c8198b9fe6db349a00b5ca6c124b5adcb381d6f7f48ffd5099ddf14a014817322320c48a3470e122622f889ced3fddca12d139125fe81'
---
> Ins::Application.config.secret_token = 'f82af2a35a05272f49f0254a6ddc06678470e771e67afb6bab00bcba41432390046adfa3bb83f8f3e2d8de02f47141d945d0000d2e24914a325ff26eeb327572'
すると、config/initializers/secret_token.rbだけが差分があると言われます。この値はRailsのサイトによるとSessionに使われるそうです。

さて、昨日やったのと同じようにapp2の方にscaffoldを実行してみます。
 cd app2/Ins/ 
 rails generate scaffold user name:string tel:integer introduction:string 
もとの場所に戻って、再度diffとってみます。
 cd ../.. 
 diff -r app1/Ins/ app2/Ins/ 
今度はさっきのsecret_token.rb以外に、以下のファイルが違うと言われます。

Only in app2/Ins/app/assets/javascripts: users.js.coffee
Only in app2/Ins/app/assets/stylesheets: scaffolds.css.scss
Only in app2/Ins/app/assets/stylesheets: users.css.scss
Only in app2/Ins/app/controllers: users_controller.rb
Only in app2/Ins/app/helpers: users_helper.rb
Only in app2/Ins/app/models: user.rb
Only in app2/Ins/app/views: users
Only in app2/Ins/db: migrate
Only in app2/Ins/log: development.log
Only in app2/Ins/test/fixtures: users.yml
Only in app2/Ins/test/functional: users_controller_test.rb
Only in app2/Ins/test/unit: helpers
Only in app2/Ins/test/unit: user_test.rb

diff -r app1/Ins/config/routes.rb app2/Ins/config/routes.rb
1a2,3
>   resources :users
> 


13個もあるので、重要っぽいのから見ていきます。
重要なのは、config/routes.rbかな?
routes.rbはアプリケーションで受け付けるURLを指定するスクリプトだそうです。
scaffoldによって、resources :users という一行が追加されてます。
この一行の意味は、以下のメソッド+URLの処理を受け付ける、という意味です。

GET/usersindexすべてのuser情報を表示
GET/users/newnewuser作成画面を表示
POST/userscreateuserの作成
GET/users/:idshow一件のuser情報を表示
GET/users/:id/editedituser修正画面の表示
PUT/users/:idupdateuser修正
DELETE/users/:iddestroyuser削除

受け付けたURLはcontrollerで処理されるそうです。
そういえば、RubyはMVCモデルだそうです。
controllerで処理を受け付けて、modelでロジックを操作して、html.rbでページを返す。
J2EE5階層モデル、JSP - Servlet - Service - Entity - Persistence or Other System との比較はおいおい調べていきます。

閑話休題。
controllerは、app/controllersの中に置かれる、xxxx_controller.rbです。今回はusers_controller.rbですね。中を少し覗いてみます。

class UsersController < ApplicationController
  # GET /users
  # GET /users.json
  def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @users }
    end
  end

  # GET /users/1
  # GET /users/1.json
  def show
    @user = User.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @user }
    end
  end
・
・
・
controllerは、ApplicationControllerを継承するクラスです。その中のメソッドがurlに応じて呼び出されます。
例えばindexは/users で呼び出されます。
indexメソッドでは、
 @users = User.all
インスタンス変数@usersにUserクラスのallラメソッドですべてのUserオブジェクトをDBカラ取得しています。このUserクラスはScaffoldで作られたModelクラスですね。ソースコードはapp/model/user.rbです。

次からの行、

respond_to do |format|
   format.html # show.html.erb
   format.json { render json: @user }
end

respond_toはリクエストの形式に応じたレスポンスを返すことのできるメソッドで、この場合はhtmlもしくはjsonを返すことができるようになっています。

今日はここまで。


2012年11月6日火曜日

9日目:jRubyでscaffoldを試してみる。

RubyといえばRails、RailsといえばScaffoldでしょ!と勝手に言って、Scaffoldを試してみます。
Scaffoldとは、データベースのテーブルを操作(カラム作ったり、消したり)するアプリをコマンドで作成できる仕組みです。
手順
①プロジェクトを作って、Railsをセットアップします。
②Scaffoldコマンドでアプリを作ります。
③rakeコマンドでDBをセットアップします。
④warblerでアプリをWarファイル化します。
⑤Tomcatに乗せて動かします。
⑥動かないので、ちょちょっといじって動くようにします。


①プロジェクトを作って、Railsをセットアップします。
プロジェクト名はScaffoldInspectとしました。

・ターミナルやコマンドラインツールで、Eclipseのワークスペースに行きます。デフォルトではユーザのホームディレクトリのworkspaceという名前のディレクトリです。そこで、Railsコマンドを打ちます。
 rails new {プロジェクト名} 
これで、作ったプロジェクトにRailsがセットアップされます。

②Scaffoldコマンドでアプリを作ります。
 cd {プロジェクト名} 
 rails generate scaffold user name:string tel:integer introduction:string 
rails generate scaffoldがScaffoldでアプリを作るコマンド。それ以降はデータの型定義です。

③rakeコマンドでDBをセットアップします。
 rake RAILS_ENV=production db:migrate 
これでDBにテーブルが作られます。
プロジェクト中のdb/production.sqlite3の中を覗くと、usersというそれっぽいテーブルが作られているのがわかります。

④warblerでアプリをWarファイル化
 warble config 
 warble war 
これで{プロジェクト名}.warというwarファイルが作成されます。

⑤Tomcatに乗せて動かします。
作ったwarファイルを{Tomcatのインストールフォルダ}/webappにコピーします。

⑥動かないので、ちょちょっといじって動くようにします。
これで動くぜ!と思って、http://localhost:8080/sm/users にアクセスすると
2つの理由で動きません。

We're sorry, but something went wrong.

なんて言って怒られる。この理由は
・dbファイルがコピーされない。
・scssがコンパイルされてない。
さて、解決します。
そのまま動かそうとすると、まずはlocalhost.logに以下のようなエラーが出ます。
ActiveRecord::JDBCError (The driver encountered an unknown error: path to '/Applications/apache-tomcat-7.0.32/webapps/{プロジェクト名}/WEB-INF/db/production.sqlite3': '/Applications/apache-tomcat-7.0.32/webapps/{プロジェクト名}/WEB-INF/db' does not exist):
ふむ。確かにdbファイルが無い。
しょうがないので、作ります。
mkdir /Applications/apache-tomcat-7.0.32/webapps/{プロジェクト名}/WEB-INF/db
cp db/production.sqlite3 /Applications/apache-tomcat-7.0.32/webapps/{プロジェクト名}/WEB-INF/db/
この場所だと再デプロイすると消えちゃうので、運用したい場合は別の場所にDBおいたほうがいいですね。
さてTomcatを再起動後、再度アクセスするとエラーが変わります。
ActionView::Template::Error (application.css isn't precompiled):
scssがコンパイルされていないんでしょう。
予めコンパイルしておく、という方法がいいんでしょうが、ここでは動的にコンパイルしてくれるように設定します。
 /Applications/apache-tomcat-7.0.32/webapps/{プロジェクト名}/WEB-INF/config/application.rbのL57行目あたり
    # config.assets.enabled = true ↓↓↓
    config.assets.enabled = false
にします。
最後の設定はホントはデプロイする前にやっておいたほうがいですね。
この対応は嘘でした。これだとJavaScriptが読み込めなくてDestroyとかが動かない。ホントの対応はこちら。
で、Tomcatを再起動。再度、http://localhost:8080/sm/users にアクセスすると



こんな画面が出たら成功! New Userでデータを作ったり弄ったりできます。

簡単だなぁ。次回以降、Railsで何をやっているかもうちょっと深掘りしていきたいと考えています。

2012年11月5日月曜日

8日目:RubyのWarファイルを作って動かしてみる。

Ruby勉強も8日目。Rubyって言ったらRailsでしょ?
ということで、Ruby on Railsやってみます。
ご存じない方の為、Ruby on Railsの説明をします。
Rubyが有名になったのも、Ruby on Railsが出たからだ!という私の勝手な思い込みを生むほど有名な、Rubyを使ってWebアプリケーションを作るためのフレームワークです。

実践派の私としては、最初にwarファイルをTomcatにデプロイするところまでやっちゃいます。
①JRubyにパスを通します。
②Ruby on RailsのGemと、WarbleのGemを入れます。
③RailsのコマンドでWebアプリケーションを作って、Warbleでwarを作ります。
④Tomcatをダウンロードしてきて、Tomcatにデプロイします。

さて、やってみます。

①JRubyにパスを通します。
昨日の記事でRuby開発環境を構築しましたが、コマンドラインでRubyコマンドを実行できるようにはしていませんでした。
Railsを使うためにはコマンドがあったほうがやりやすいので、コマンドにパスを通します。
Macの場合は、ターミナルを使って、.bash_profileに、
 export PATH={jrubyをインストールしたディレクトリ}/bin:$PATH 
windowsの場合は、マイコンピュータを右クリックして、環境設定(だったっけ・・・・)のPathに
{jrubyをインストールしたディレクトリ}/bin;
を追加してください。

②Ruby on RailsのGemと、WarbleのGemを入れます。
Macだったらターミナル、Windowsだったらコマンドプロンプトを使って、以下のコマンドを実行してください。
 gem install rails 
ちょっと時間がかかるので、気長に待ってください。これでRailsがインストールされます。ついで、Warblerをインストールします。WarblerはWarファイルを作ってくれるGemです。
 gem install warbler 
これで準備は完了、次はWebアプリを作っていきます。

③RailsのコマンドでWebアプリケーションを作って、Warbleでwarを作ります。
続いて、以下のコマンドを打ってください。
 rails new application 
ずらずらずらっといろんなメッセージが出て、Webアプリケーションが作られます。
Railsについては、今後勉強しようと考えています。まずは動くところを味わいたい!
引き続き、war化します。作ったapplicationディレクトリに移動して、
 cd application 
warblar用の設定ファイルを作ったアプリケーションに置きます。
 warble config 
置いたらWarファイルを作成します。
 warble war 
これで、application.warファイルがカレントディレクトリに作成されました。

④Tomcatをダウンロードしてきて、Tomcatにデプロイします。
Warファイルができたので、Warファイルを動かすWebアプリケーションをダウンロードします。もちろんGlassfishでもJettyでもJBossでもWeblogicでも、動くはず!ですが、ま、基本のTomcatで動かしてみます。
・Tomcatをここからダウンロード

Zipをダウンロードして、展開してください。
展開したら、Tomcatのディレクトリの中のbin/startup.shを実行してください。
実行できたら、Tomcatのディレクトリの中のwebappsに③で作ったapplication.warを配置してください。

これで完了!
ブラウザで確認してみましょう。
http://localhost:8080/application
こんな画面が出たら成功です。
簡単ですね!

さて、これからRuby on Railsを勉強して行きましょうかね。

2012年11月4日日曜日

7日目:Ruby環境を構築する。

さて。初めてのRubyを読了したところで、Rubyの開発環境を揃えてみます。
もちろん、生粋のJavaプログラマの私としてはJava的な開発環境を揃えます。
使うのは以下。
・Java
・JRuby・Eclipse(Juno)
・Eclipseの設定
できるだけ環境を汚さずに環境を作っていきます。

・Javaのインストール
こちらのサイトからJavaをダウンロードしてください。
①チェックを入れて
②あなたのOS用のJavaをダウンロードしてください。Windows x64の方が多いでしょう。

ダウンロードしたファイルを実行して、インストールを行なってください。

・JRubyのインストール
①Zipをダウンロードしてください。

ダウンロードが終わったら、展開してください。展開するだけで大丈夫。

・Eclipseのインストール
こちらのサイトからEclipseをダウンロードしてください。
たくさんあるうちのどれでも良いのですが、一番上のものがいいでしょう。
①一番上のものをダウンロードしてください。

ダウンロードしたファイルを展開してください。展開するだけで大丈夫。

・Eclipseの設定。
↓Eclipseを起動して、ツールバーのHelp→Install New Software..を選択します。
私はMacですが、Windowsの方はEclipseのウインドウのツールバーにHelpがあると思います。

↓Work With:でJuno - http://download.eclipse.org/releases/junoを選択します。


↓Programming Languages→Dynamic Languages Toolkit - Ruby Development Toolsを選択して、
ウインドウの一番下のNextボタンを押します。
あとはNextボタンを連打していくんですが、途中で利用許諾に合意する必要があります。
↓この画面でFinishボタンを押したら完了。
Yesボタンを押してEclipseを再起動します。


再起動したら、ツールバーのEclipse→環境設定を開きます。Windowsだったら、Window→Preferencesだったかな?

Ruby→Interpretersを選択します。

Addボタンを押します。
Interpreter executableの右のBrower..ボタンを押して、展開したJRubyフォルダのbin/jrubyを選択します。Windowsだったら、bin/jruby.batかな。
OKボタンを押したら、Rubyでプログラミングしまくりです!
文法チェックしてくれるし、コンテンツアシストはしてくれるし、超便利。


Vimも悪くはないと思いますが、Rubyやる人はぜひ一度、EclipseでのRuby実装をお試しあれ!

2012年11月3日土曜日

6日目:初めてのRuby読了!

「初めてのRuby」、この本、Java、JavaScriptライクな私にとってとってもいい本でした。
なぜかというと、Rubyの仕様に特化しているからです。変数の説明だとか、計算式の説明だとか、プログラミング言語の基礎はすっ飛ばしている。
だから、薄い本なんですが、とても中身が濃い!どのページにも新しい発見がありました。
他のプログラミング言語を使っている人がRubyを勉強するために最初に手に取る本として凄くオススメです!

本日で、始めてのRuby読了!
さて、今日勉強した内容。

・gemって?
パッケージ化された(セットになった).rbファイル群をロードする仕組みらしいです。
ライブラリを使いたい時は、gemコマンドでライブラリを取得して使う。
使うときはソース上でrequire() と gem()を使う。
例えばDBアクセスの例。

require("rubygems") #Rubyに組み込まれているrubygems.rbを読み込む。
gem "activerecord" #activerecordというGemをセットアップする。
require("active_record") #Gemの中に入っているactive_record.rbを読み込む。
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
ActiveRecord::Base.connection.create_table("users") do |table|
  table.string(:name, :null=>false)
  table.string(:tel, :null=>false)
  table.timestamp(:created)
end
class User < ActiveRecord::Base
end
User.create!(:name => "saytone", :tel=>"090-0000-0000")
p User.find_by_name("saytone")

便利ですねー。DBアクセスも簡単。
gemコマンドでGemファイルはインストールできますが、Rubyラインタイムにインストールされるっぽい。Rubyランタイムの近くにgemsってディレクトリがあって、そこに.Gemの設定ファイルだとかrbファイルだとかがインストールされてる。
んー。あまり環境を汚したくないので、gemはアプリケーションごとに持ちたいなぁ。JavaのWebプリケーションで使う.jarは.warファイルに埋め込むように。

・オブジェクトに存在しないメソッドが呼び出されたときはmethod_missingが呼ばれる。

class MyClass
  def method_missing(method_name,*args)
    p "#{method_name} called"
  end
end
myObj = MyClass.new()
myObj.noSuchMethod();

オシャレ。
でもコレ、存在しない「パラメータ」呼び出しでも呼ばれるよね?Rubyはメソッド実行に()が要らないもの。。。()つけずにメソッド呼び出しはヤバイですよぅ。

・Proc.newはprocとも書ける。

まぁ、そういうメソッドがあるってことですね。
myProc = proc do
  p "proc call"
end
myProc.call()



というわけで
!!!!!読了!!!!!
次回は、Rubyの開発環境を整備してみます。

私は生粋のJavaプログラマなので、生粋のJava的Ruby開発環境を作ってみます!


2012年11月2日金曜日

5日目:慣れてきた!かな?

Ruby勉強5日目!

今日も読み続ける。
だんだんサンプルコードも悩まずに理解できるようになってきた。

・&をつけると、Procオブジェクトと処理ブロックを変換できる。
処理ブロック→Proc

def func(&callback)
  p callback
  callback.call("callback arg")
end
func do |i|
  p i
end
func関数の引数に&が入ってますね。この変数に処理ブロックがProcオブジェクトに変換された値が入ります。

Proc→処理ブロック

proc = Proc.new do 
  p "func"
end
2.times(&proc)
2.timesの引数に&procを渡しています。&を省略するとエラーが出ます。


・extendsの代わりに、<

class MyClass < Object
end


・staticはクラス内でクラス名.メソッド名というメソッドを定義する。
ちなみに、クラスは定数だそうです。だから、Objectは::Objectとも書ける。

・クラス名.new()でインスタンス化。
クラスメソッドでインスタンス化するようなスタイルはとてもわかりやすくてイイ!
コンストラクタメソッドはinitializeだそうです。

・attr_accessor :インスタンス変数
でアクセサメソッドの作成。attr_reader,attr_writerもある。
便利ね。
class MyClass < Object
  def initialize(value="defalut")
    @value = value
  end
  attr_accessor :value
end
myObject = MyClass.new
p myObject.value
attr_xxxに渡せるのはシンボル。
。。。Javaプログラマの私は、ここで、ん?となる。
「ん?シンボルでインスタンス変数が指定できるの?」
実は、attr_accessor :value は attr_accessor "value"とも書ける。
んー。どういうこと?

・え?def func= value end って、何事?
メソッドに、値代入????
なんだろ、と思っていたんですが、Rubyって、メソッド名の最後に=が使えるらしい。
だから、「func」が関数名なんではなくて、「func=」が関数名。
class MyClass
  def func= value
    p "oh... "+ value
  end
end
myObj = MyClass.new()
myObj.func=("value")
と書ける。ふーん。
でも、試してた所、最後に=がつくメソッド名は、クラスにつける時と、グローバルに付ける時と意味がかわるっぽい。



def func= value
  p "oh... "+ value
end
func=("value")
だと、何も出力されない。トップレベルの関数はObjectクラスのメソッド追加になるらしいんだけれど、なんで実行されないの????誰か知っていたら教えて下さい。


・aliasでメソッド名に別名を付けられる。
def func
  p "func"
end
alias dummy func
dummy
な感じ。

・オーバーライドメソッドの中でsuperとやると、オーバーライドしている親クラスのメソッド実行。
やめてよ!( )なしで処理を実行するの!
クラスをfreezeすれば変更できなくなるので、私はそうします。

・$で始まる変数は組込み変数
例えば$>は標準出力
コチラ参照
http://doc.ruby-lang.org/ja/1.8.7/class/Kernel.html

・大文字もしくは_で変数宣言すると定数。
でも、値は上書きできちゃう。ワーニングは出るけれども。
ダメっしょ、上書きさせちゃ。

・::変数名はトップレベルの定数
::CONSTANTは、実はObject::CONSTANTのObjectが省略されたもの。

・クラス名も定数。
::MyClassで参照できる。

・メソッドのスコープ定義はあとからメソッド名をシンタックス定義して変更できる。



class MyClass
  def func
  end
  private :func
end
myObj = MyClass.new()
myObj.func();
モチロン、これはエラーとなります。

・オブジェクトにメソッドを追加できる。その名も特異メソッド
obj = Object.new
def obj.func(value)
  p value
end
obj.func("data")

defって柔軟ね。

・オブジェクトのクラスにもメソッドを追加できる。
obj = Object.new()
class << obj
  def func
    p "new func"
  end
end
obj.func
こんな書き方。


・selfとthisの違い。
selfはクラスを示すことがある。


class MyClass
  p self.class #このselfはクラスを示す
  def func
    p self #このselfはインスタンス化時のオブジェクトを示す。thisと一緒
  end
end
こんな感じ。

・コメントは#でかける。
// や /* */ はダメ。たぶん、Rubyはビバ正規表現だからでしょう。

・モジュール
メソッドの中身を持てるインターフェースって感じでしょうか。


module MyModule
  def funcModule
    p "module func called"
  end
end

class MyClass
  include(MyModule)
end

myObj = MyClass.new()
myObj.funcModule()


ん?でも、これって、多重継承の悪の歴史を繰り返してない?どのメソッド実装が使われるか曖昧だから、多重継承って避けられてた気が。。。
確認!


module MyModule
  def funcModule
    p "module func called"
  end
end
module MyModule2
  def funcModule
    p "module2 func called"
  end
end
class MyClass
  include(MyModule)
  include(MyModule2)
end

myObj = MyClass.new()
myObj.funcModule() 
出力されるのは"module2 func called"。
後からincludeしたほうがそれまでのメソッドを上書きしてこの動きになっているのは予想通りなんですが、いいのかな?

・宇宙演算子 <=> 名前がカッコイイ。
比較演算子で、左辺、右辺の大小で-1,0,1を返す。
名前がカッコイイ。

・モジュールの中にクラスが書ける。

module MyModule
  class MyClass
    def func
      p "print"
    end
  end
end

ほう。
ちなみにインナークラスも書ける。

class MyClass
  class MyInnerClass
    def func
      p "print"
    end
  end
end
myObj = MyClass::MyInnerClass.new()
myObj.func()


・::の連続って、なぁに?
よくRubyのサンプルコードで、Foo::Bar::Hoge とか見ますよね。
::は定数呼び出しですよね。定数の定数?あ、そういえば、クラスは定数なんでした。
じゃ、モジュールも定数っぽいですよね。じゃ、入れ子のモジュールか?
確認。

module MyModule
  module MyInnerModule
    module MyInnerInnerModule
      class MyClass
        def func
          p "print"
        end
      end
    end
  end
end
myObj = MyModule::MyInnerModule::MyInnerInnerModule::MyClass.new
myObj.func()
そういう事ですか。納得。

・オーバーロードは出来ない。
残念。

・requireで他ファイルの読み込み
ファイルrequired.rb

###required.rb######
class Required
  print "this is Required class"
end
####################

を用意して、

require("required.rb")
Required.new()
requireでそれを読み込むと、外部ファイル定義のクラスが呼び出せます。.rbは省略可。
require("required") #.rbは省略可
Required.new()



2012年11月1日木曜日

4日目:色々な書き方がありますねぇ。Rubyって。

Javaダイスキっ子のRuby勉強4日目。初めてのRubyで勉強しています。
今日はp140まで。
さて、勉強した内容です。

・defの外側の変数は内側からは見られない。
↓みたいなのはダメ。

value="test"
def func
  p value
end
func

JavaScriptダイスキな私には意外です。

・Procで処理ブロックをオブジェクト化できる。

proc = Proc.new do p 1+1 end
proc.call
こんな風に。
んー。でも、Proc.newってProcオブジェクトのインスタンス化ですよね?
だったら、↓みたいに書けると思ったんだけれども、エラーになる。

proc = Proc.new(do p 1+1 end)
proc.call

不思議。誰か知っていたら教えて下さい。


・クロージャーって、オブジェクトがあればいらなくね?
処理ブロックは外側で定義された変数を見れる。処理ブロックが有効なうちはその変数も有効で、同じ変数が生き続けるので、以下の様なことができる。
def createCountupProc
  value = 0
  return Proc.new do
    p value+=1
  end
end
countupProc = createCountupProc;
3.times() do countupProc.call end
→1、2、3って表示される。コレをクロージャーって言うらしいけれど。。。
オブジェクトがあれば、コレ要らなく無いですか?
Javaでもクロージャーの導入が検討されているらしいですが、どう使うんだろう?

・文字の配列列を作るとき、%wが便利
words = %w[word1 word2  word3]
words.each() do |word| p word end


""をつけなくても、文字列をつくれる。が、読みにくいなぁ。。。。

・block_given?で処理ブロックが与えられたかを確認できる。
関数に処理ブロックを与えることができることは昨日やりました。
で、処理ブロックが与えられたかをblock_given?で確認できます。

def func
  if block_given?
    yield()
  else
    p "block not given"
  end
end
func do p "block give"
end
func