This document summarizes and compares Ruby HTTP client libraries. It discusses the sync and async APIs of 16 libraries including Net::HTTP, HTTPClient, and Faraday. It covers their compatibility, supported features like keep-alive connections, and performance based on benchmarks. The document recommends libraries based on priorities like speed, HTML handling, API clients, and SSL support. It encourages readers to check the detailed feature matrix and report any errors found.
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等
※クラスオブジェクトのキャッシュは
リークの元なので普通やらない
20. 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
29. 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
30. 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
38. ウェブ開発 (JRuby on Rails)
Ruby on Rails - http://rubyonrails.org
ウェブアプリケーションフレームワーク
フルスタック
CoC: (XML)設定より規約(に従って開発)
DRY: 同じことを繰り返さない
39. Railsツアー 1/7:
アプリケーションの生成
MVC、テスト、サードパーティライブラリ等
常に同じディレクトリ構成
% jruby -S rails new myapp
create
create README
create Rakefile
...
create vendor/plugins
create vendor/plugins/.gitkeep
run bundle install
Fetching source index for http://rubygems.org/
Using rake (0.9.2.2)
Installing multi_json (1.0.3)
...
Installing sass-rails (3.1.5)
Installing uglifier (1.1.0)
Your bundle is complete! Use `bundle show [gemname]` to
see where a bundled gem is installed.
41. Railsツアー 3/7: DBマイグレーション
スクリプトによるDBスキーマ履歴管理
class CreateTodos < ActiveRecord::Migration
def change
create_table :todos do |t|
t.boolean :done
t.string :description
t.timestamps
end
end
end
% jruby -S rake db:migrate
== CreateTodos: migrating
====================================================
-- create_table(:todos)
-> 0.0040s
-> 0 rows
42. Railsツアー 4/7: サーバ起動
% jruby -S rails server
scaffoldだけ => Booting WEBrick
=> Rails 3.1.3 application starting in development
でも動く on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2011-11-28 15:58:15] INFO WEBrick 1.3.1
[2011-11-28 15:58:15] INFO ruby 1.8.7 (2011-11-27)
[java]
43. Railsツアー 5/7: 生成されたコード
モデル class Todo < ActiveRecord::Base
end
<%= form_for(@todo) do |f| %>
<div class="field">
<%= f.label :done %><br />
ビュー <%= f.check_box :done %>
</div>
コントローラ <div class="field">
<%= f.label :description %><br />
<%= f.text_field :description %>
</div>
class TodosController < ApplicationController<div class="actions">
def index <%= f.submit %>
@todos = Todo.all </div>
respond_to do |format| <% end %>
format.html # index.html.erb
format.json { render :json => @todos }
end
end
def create
...
end
44. Railsツアー 6/7:
ActiveRelation (Arel)
遅延SQL生成用のDSL
Todo.where(:done => false)
SELECT "todos".* FROM "todos" WHERE "todos"."done" = 'f'
Todo.where(:done => false).where('created_at < "2011-11-29"')
SELECT "todos".* FROM "todos" WHERE "todos"."done" = 'f' AND
(created_at < "2011-11-29")
Todo.where(:done => false).order("created_at DESC").limit(1)
SELECT "todos".* FROM "todos" WHERE "todos"."done" = 'f'
ORDER BY created_at DESC LIMIT 1
スコープ class Todo < ActiveRecord::Base
scope :finished, where(:done => true)
end
Todo.finished.size
SELECT COUNT(*) FROM "todos" WHERE "todos"."done" = 't'
49. Java SE 7: InvokeDynamic
新たなメソッド呼び出しバイトコード
bootstrapメソッド
dynamic language support (java.lang.invoke.*)
MethodHandle
MethodType
SwitchPoint
CallSite