7. Rubyツアー 1/8: クラス定義
public class Circle extends Shape { class Circle < Shape
private final int radius; def initialize(radius)
public Circle(int radius) { @radius = radius
this.radius = radius; end
} attr_reader :radius
public int getRadius() { def area
return radius; Math::PI * (@radius ** 2)
} end
public double getArea() { end
return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area
}
public static void main(String[] args) {
double area = new Circle(2).getArea(); extends → <
継承は単一継承
System.out.println(area);
}
}
メソッド定義 → def
コンストラクタ → initialize
8. Rubyツアー 2/8: インスタンス変数
public class Circle extends Shape { class Circle < Shape
private final int radius; def initialize(radius)
public Circle(int radius) { @radius = radius
this.radius = radius; end
} attr_reader :radius
public int getRadius() { def area
return radius; Math::PI * (@radius ** 2)
} end
public double getArea() { end
return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area
}
public static void main(String[] args) {
double area = new Circle(2).getArea(); this → @
System.out.println(area);
}
}
attr_readerはアクセサメソッド定義用メソッド
9. Rubyツアー 3/8: 動的型付け
public class Circle extends Shape { class Circle < Shape
private final int radius; def initialize(radius)
public Circle(int radius) { @radius = radius
this.radius = radius; end
} attr_reader :radius
public int getRadius() { def area
return radius; Math::PI * (@radius ** 2)
} end
public double getArea() { end
return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area
}
public static void main(String[] args) {
double area = new Circle(2).getArea(); 変数に型なし
System.out.println(area);
} duck-typing
}
引数の型・数の違いによるメソッドoverloadなし
10. Rubyツアー 4/8: 全てが値を持つ
public class Circle extends Shape { class Circle < Shape
private final int radius; def initialize(radius)
public Circle(int radius) { @radius = radius
this.radius = radius; end
} attr_reader :radius
public int getRadius() { def area
return radius; Math::PI * (@radius ** 2)
} end
public double getArea() { end
return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area
}
public static void main(String[] args) {
double area = new Circle(2).getArea(); return不要
}
System.out.println(area);
文の値は最後の式
}
11. Rubyツアー 5/8:
全てがオブジェクト、全てがメソッド
public class Circle extends Shape { class Circle < Shape
private final int radius; def initialize(radius)
public Circle(int radius) { @radius = radius
this.radius = radius; end
} attr_reader :radius
public int getRadius() { def area
return radius; Math::PI * (@radius ** 2)
} end
public double getArea() { end
return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area
}
public static void main(String[] args) {
double area = new Circle(2).getArea(); Circle: 定数
System.out.println(area);
} a*2 == a.*(2)
}
Circle.new:
クラスオブジェクトのnewメソッドを呼び出す
12. Rubyツアー 6/8: ブロック(クロージャ)
def aaa(name, &block)
File.open(name) do |file| (1) File.open用ブロック
file.each_line do |line|
yield line
ブロック実行後に自動close
(2) end (1)
end
end
(2) each_line用ブロック
1行読み込む毎に呼ばれる
aaa('a.txt') do |line|
p line (3)
end
(3) aaa用ブロック
people.group_by { |e| e.lang } aaa内部のyieldに呼ばれる
button1 = ...
label1 = ...
button1.on_action do |event|
label1.text = 'sending...'
end
← その他利用例
13. Rubyツアー 7/8:
Mix-in、オープンクラス
module Utils
def name Mix-in: 実装の継承
self.class.name 実装 Utilsモジュールの実装を
end
end
class Book
BookクラスにMix-in
include Utils 継承
def say
"Hello from #{name}"
end
end
obj = Book.new
p obj.say #=> "Hello from Book"
class Book
オープンクラス:
def say Bookクラスのsayメソッド
"I'm #{name}"
end を再定義
end
p obj.say #=> "I'm Book"
14. Rubyツアー 8/8: フックメソッド
class Base
@@all = [] inherited: クラスが継承
def self.inherited(klass)
@@all << klass
された場合に、継承したクラ
end スを引数に呼ばれる
end
class Sub < Base
p @@all
その他: included、
end method_added、
class SubSub < Sub method_removed、
p @@all
end method_missing、
※@@はクラス変数の接頭辞 const_missing等
※クラスオブジェクトのキャッシュは
リークの元なので普通やらない
18. Java連携 (Java -> Ruby)
JavaからRubyライブラリを利用
import org.jruby.embed.ScriptingContainer;
public class HelloWorld {
public static void main(String[] args) {
ScriptingContainer ruby = new ScriptingContainer();
ruby.runScriptlet("puts "hello,world!"");
}
source 'http://localhost/'
}
group :development do
host 'localhost'
port 12345
reloadable true
例: 独自定義ファイル解析の debug true
end
DSL処理系として group :production do
host 'www.example.com'
end
23. Javaテスト (RSpec)
RubyとJRubyの利点を活かしてJavaをテスト
describe 'ScriptingContainer#put' do
before :each do
RSpec: @x = org.jruby.embed. ScriptingContainer.new
end
振る舞いをテスト it "sets an object to local variable" do
obj = Object.new
http://rspec.info @x.put("var", obj)
@x.run_scriptlet("var").should == obj
% jruby -S rspec jruby_spec.rb end
.. it "overrides the previous object" do
obj = Object.new
Finished in 0.044 seconds @x.put("var", obj)
2 examples, 0 failures @x.put("var", nil)
% @x.run_scriptlet("var").should be_nil
end
end
24. Javaテスト (JtestR)
JtestR: 各種Ruby用テストライブラリ同梱
http://jtestr.codehaus.org/
describe "X509Name" do
it "should use given converter for ASN1 encode" do
converter = mock(X509NameEntryConverter)
name = X509Name.new('CN=localhost', converter)
converter.stubs('getConvertedValue').
with(DERObjectIdentifier.new(CN), 'localhost').
returns(DERPrintableString.new('converted')).
times(1)
name.toASN1Object.to_string.should == '...'
end
end