Hatena::Groupstudyroom

文::字

2010-10-16

[] rbp-book - things_go_wrong.txt メモ 16:15  rbp-book - things_go_wrong.txt メモ - 文::字 を含むブックマーク

hgstueoeyyhgstueoeyy2013/08/02 23:17kyzratuvezsppn, <a href="http://www.ayxytvsxvf.com/">fscxxwpsjf</a> , [url=http://www.fffgdqgrbe.com/]udotqlotuv[/url], http://www.kintlxurtg.com/ fscxxwpsjf

MichelMichel2013/12/28 22:32Hey! Let me know if this is helping your soohcl project! That POOR pretty blue lobster!!! That's a great pic! So what is this project about exactly?! Hope ya do well! Rock on in the free world sir! =)

VelVel2013/12/29 15:41I'm learning to<a href="http://nwaytpqv.com"> maetsr</a> several different blogging platforms as part of my web development program. I'm enjoying it very much, Deb. Please bookmark me & check in periodically when you get time. }:-D-

2010-10-13

[] rbp-book - fp.txt メモ 22:44  rbp-book - fp.txt メモ - 文::字 を含むブックマーク

http://github.com/sandal/rbp-book/blob/master/manuscript/unmerged/fp.txt

  • tail call optimization (末尾最適化)
  • MenTaLguY's 'lazy.rb' (L166)
  • promise (lazy.rb)
  • スペースが無い (L459)
  • "All code blocks in Ruby are lazy, and are not executed until explicitly called." (L476)
  • mutable state
  • "Although Ruby is object oriented, and therefore relies heavily on mutable state, we can write non-destructive code in Ruby." (L493)
  • Enumerable#each_with_object
  • 再帰は重い (L577)
    • メソッド呼び出しが重いため
  • "`Enumerable#inject` is a favorite feature among Rubyists for accumulation." (L676)
  • map の実装
    • 再帰, inject, each の順に重い理由
  • 副作用はなるべく起こらないようにする
  • タイポ proces -> process (L728)
  • 状態変化を完全にさけようとするのではなく、副作用が起こらないようにする
  • Module#module_function
  • module 定義の中で extend self するのと Module#module_function を使うときの違い
module MyModule
  extend self
  def some_method
  end
end
  • なるべく、Comparable とか Enumerable をインクルードして自分のライブラリを作ったほうがいい
    • ほかの人にも使いやすくなる

2010-10-12

[] rbp-book - io.txt メモ 23:39  rbp-book - io.txt メモ - 文::字 を含むブックマーク

http://github.com/sandal/rbp-book/blob/master/manuscript/unmerged/io.txt

  • when は , で区切ると or みたいなことができる (L99)
  • finite state machine (有限状態機械 = 有限オートマトン)
  • マッチした値を 1 つだけ取り出したければ String[]、2 以上取り出したければ Perl スタイルのグローバ##変数を使う ($1 とか) (L235)
  • '"find a needle in the haystack" extraction' (L740)
  • traverse という英単語、glob みたいな操作によく使われる感じか (L804)
  • Pathname#+ 便利
    • Pathname 自体便利そう
  • 'we can skip overthe details.' (typo) L859)
  • IO(?)#rewind
  • temp << some_data (L1026)
  • File オブジェクトは Enumerable をインクルードしているため、inject が使える (L1172)
  • File#lineno (L1209)
  • Enumerable#zip (L1254)
  • ファイルを部分的に更新する場合 (L1272)
    • r+ でもなく全体を書き換えるのでもない方法 = tempfile を使ってから対象ファイルに mv するとよい
  • パフォーマンスを考えてメモリに載せたりするより一行ずつ読みながら処理したほうがよい (L1448)

[] クラスの中で別のオブジェクトを new する場合のテスト方法 22:06  クラスの中で別のオブジェクトを new する場合のテスト方法 - 文::字 を含むブックマーク

こういうやつ。

describe MyClass, "execメソッドが実行されたとき:"  do

  it "初期化時に生成したHerClassのインスタンスのrunメソッドを呼び出す" do
    @her_mock = mock("her")
    HerClass.should_receive(:new).and_return(@her_mock)
    @my = MyClass.new
    @her_mock.should_receive(:run)
    @my.exec
  end

end

(オブジェクトが保持するインスタンスとの協調の検証 - 日記より引用)

Mechanize とか外部の便利ライブラリを使って自分で何か作るときとかにありがちだと思うんだけど、どうしてもこういう「new した結果返ってきたオブジェクトに対して何らかのメソッド呼び出しが行われること」というのをテストしたくなる。

今まで自分も上記のようにやっていたんだけど、なんかどうしても読みづらくなってしまう気がする。DSL なのに読みづらいのはダメな感じがするので、できればこういう風に書きたい。

    HerClass.should_receive(:new).and_return(
      mock("her").should_receive(:run)
    )
    @my = MyClass.new
    @my.exec

このほうが「HerClass が new されて、さらに生成されたオブジェクトの #run が呼び出される」というのが把握しやすいと思うんだけど、should_receive メソッドが Mock オブジェクトではなく Spec::Mocks::MessageExpectation を返すため、テストは失敗する。

次善策としてこういうのはどうだろう。

    HerClass.should_receive(:new).and_return(
      mock("her").tap {|m| m.should_receive(:run) }
    )   
    @my = MyClass.new
    @my.exec

Object#tap を使って Mock オブジェクトをつかまえた上で should_receive() メソッドを呼び出している。これなら動くんだけどテストの本質とは関係ない tap が出てくるのが微妙。

mock() メソッドがブロック引数をとればいいのにな、とか思ったりする。そうすればこう書ける。

    HerClass.should_receive(:new).and_return(
      mock("her") {|m| m.should_receive(:run) }
    )
    @my = MyClass.new
    @my.exec

もろもろまとめたやつを gist に貼っておいた (http://gist.github.com/622133)。実際こういうシチュエーションってあんまりないもんかな…。

2010-10-10

[] rbp-book - dynamic-toolkit.txt メモ 23:42  rbp-book - dynamic-toolkit.txt メモ - 文::字 を含むブックマーク

http://github.com/sandal/rbp-book/blob/master/manuscript/unmerged/dynamic_toolkit.txt

  • Builder はメソッドの保存に Proc ではなく Method を使っている (L214)
    • あとでオブジェクトに bind する必要があるからかな
    • でも Proc とか使っても instance_eval で bind と似たようなことできそうだけど…
  • "make sure it not" は "make sure it's not" の間違いっぽい (L228)
  • fail と raise って何が違うんだろう
  • BlankSlate の実装、手元の irb で動かない…
  • instance_eval でオブジェクト初期化させる際には getter っぽい setter を用意すると良い (L782)
  • クラスのメソッドを再オープンして上書きしてしまう場合の対処として、上書きされるほうで検知するのはやりすぎ (L1403)
  • モジュールによる拡張が使えない場合 = 数や Symbol クラス = new できないもの (L1631)
  • Class.new がとるブロックの中で def キーワードを使ってメソッドを定義する方法 (L1753)
  • 元ネタがよく分からない (L1753)
  • cooking with gas
  • スペルミス s/accomodate/accommodate/ (L2020)
  • Module#append_features (L2146)
  • フック系のメソッド(Object#method_added, Kernel#method_added, Module#append_features, Class#inherited) ってその動作が行われた前に実行されるのかな、後に実行されるのかな
    • 後に実行されるっぽいけど、前に実行することはできないのか
    • 答えが書いてあった - L2440
  • Class#inherited は簡単な Test::Unit みたいな DSL を作るときに普通に便利そう
  • これは getter にも setter にもなる? (L2245)
  • bee's knee (http://eow.alc.co.jp/bee%27s+knees)

2010-10-08

[] rbp-book - api.txt メモ 02:24  rbp-book - api.txt メモ - 文::字 を含むブックマーク

http://github.com/sandal/rbp-book/blob/master/manuscript/unmerged/api.txt

ary = ['zero', 'one', 'two']
ary << 'three' << 'four' << 'five'
p ary # ["zero", "one", "two", "three", "four", "five"]
  • 宇宙船演算子 (spaceship operator, '<==>') を定義すると Comparable モジュールをインクルードすることができる
    • 比較系の演算子を全て使うことができるようになる

[] rbp-book - testing.txt メモ 23:25  rbp-book - testing.txt メモ - 文::字 を含むブックマーク

http://github.com/sandal/rbp-book/blob/master/manuscript/unmerged/testing.txt

module MyModule
  extend self
  def method1
  end
  def method2
  end
end
  • カスタムエラークラスのかっこいい定義方法
    • あとクラスの中にクラスを定義するとどうなるのかな、モジュールの場合との違い等あとで調べる
class LockBox
  UnauthorizedAccess = Class.new(StandardError)
  InvalidPassword = Class.new(StandardError)
end


[] フラットスコープ、クロージャ 11:02  フラットスコープ、クロージャ - 文::字 を含むブックマーク

lambda {
  shared = 0 
  Kernel.module_eval do
    define_method :set_shared do |val|
      shared = val
    end
    define_method :get_shared do
      shared
    end
  end
}.call

set_shared(:hello)
p get_shared # => :hello
p shared # NameError になる
lambda {
  MyClass = Class.new
  @my_instance_var = :in_closure
  $my_global_var = :in_closure
  my_local_var = :in_closure
}.call

p MyClass # => MyClass
p @my_instance_var # => :in_closure
p $my_global_var # => :in_closure
p my_local_var # NameError になる
my_binding = lambda {
  local_var = :in_closure
  binding
}.call
p eval('local_var', my_binding) #=> :in_closure

2010-10-05

[] irb 内でのネスト 20:39  irb 内でのネスト - 文::字 を含むブックマーク

メタプログラミング Ruby」に出てきて面白かったのでメモ。

# irb 内
s = 'abc'
irb s  # s の中に入り込む
split(//)  # => ["a", "b", "c"]
def some_method; 'hello' end  # instance_eval と同じなので特異メソッドとして定義される
exit  # s から出る
s  # => "abc"
s.some_method  # => "hello"
s.singleton_methods.include?('some_method')  # => true

[] 値渡し 20:46  値渡し - 文::字 を含むブックマーク

class MyClass
  attr_accessor :attr
end
def touch_attr(obj)
  obj.attr = :touched
end
def substitute_nil(obj)
  obj = nil 
end

obj = MyClass.new

obj.attr #=> nil 

# nil を代入しても反映されない
substitute_nil(obj)
obj #=> #<MyClass:0xb7c7cc04 @attr=:touched>

# 属性を書き換えると反映される
touch_attr(obj)
obj.attr #=> :touched

参考:

BarbaraBarbara2013/12/28 22:52It's spooky how clever some ppl are. Thnask!

JenniferJennifer2013/12/29 15:41Good to see a <a href="http://mkgtwuvyygt.com">talnet</a> at work. I can't match that.

2010-10-04

[] require 'rubygems' すると require 'yaml' されて Object になんか色々追加される 00:26  require 'rubygems' すると require 'yaml' されて Object になんか色々追加される - 文::字 を含むブックマーク

old = Object.instance_methods
require 'rubygems'
new = Object.instance_methods
p new - old
# => ["to_yaml_properties", "to_yaml", "taguri", "taguri=", "to_yaml_style"]

[] クラスメソッドの self とインスタンスメソッドの self 22:08  クラスメソッドの self とインスタンスメソッドの self - 文::字 を含むブックマーク

class MyClass
  def self.class_method; self end 
  def instance_method; self end 
end
MyClass.class_method # => MyClass
MyClass.new.instance_method # => #<MyClass:0x1023108>

[]クラスメソッドを class キーワードも def キーワードも無しで定義することは不可能なのかな 21:45 クラスメソッドを class キーワードも def キーワードも無しで定義することは不可能なのかな - 文::字 を含むブックマーク

最後の 2 つ、'Object#instance_eval() + Module#define_method()' と 'Module#class_eval() + Module#define_method()' が失敗する。

「rubyの実行モデルには「特異クラス」というものはありません」っていうのと関係してるようなしてないような…。

describe 'クラスメソッドを定義するやり方' do

  before do
    @klass = Class.new
  end

  it 'class キーワード + def キーワード (self)' do
    A = @klass
    class A
      def self.a_singleton_method; 'hello' end
    end
  end

  it 'class キーワード + def キーワード (クラス名)' do
    B = @klass
    class B
      def B.a_singleton_method; 'hello' end
    end
  end

  it 'class キーワード + 特異クラス' do
    C = @klass
    class C
      class << self
        def a_singleton_method; 'hello' end
      end
    end
  end
    
  it '特異クラス + def キーワード' do
    class << @klass
      def a_singleton_method; 'hello' end
    end
  end

  it 'Object#instance_eval() + def キーワード' do
    @klass.instance_eval do
      def a_singleton_method; 'hello' end
    end
  end
    
  it 'Object#instance_eval() + Module#define_method()' do
    @klass.instance_eval do
      define_method(:a_singleton_method) { 'hello' }
    end 
  end 

  it 'Module#class_eval() + Module#define_method()' do
    @klass.class_eval do
      define_method('self.a_singleton_method') { 'hello' }
    end 
  end 

  after do
    @klass.singleton_methods.include?('a_singleton_method').should be_true
    @klass.a_singleton_method.should == 'hello'
  end

end
# spec class_method_spec.rb 
.....FF

1)
'クラスメソッドを定義するやり方 Object#instance_eval() + Module#define_method()' FAILED
expected true, got false
./class_method_spec.rb:56:

2)
'クラスメソッドを定義するやり方 Module#class_eval() + Module#define_method()' FAILED
expected true, got false
./class_method_spec.rb:56:

Finished in 0.00516 seconds

7 examples, 2 failures

[] main オブジェクトのメソッドとインスタンス変数について 20:21  main オブジェクトのメソッドとインスタンス変数について - 文::字 を含むブックマーク

トップレベルコンテキスト main で定義したインスタンス変数は main オブジェクトが self となるスコープでしか利用できないのに対し、main で定義したメソッドはどこからも利用できる。このことに微妙な違和感を覚えるんだけど、こんなものだろうか。

self # => main
self.class # => Object

@var_in_main = 'hoge'

def put_var_in_main
  puts @var_in_main
end

put_var_in_main # 'hoge' と印字される

Kernel.methods.include?('put_var_in_main') # => true

class SomeClass
  def put_var
    put_var_in_main
  end
end

sc = SomeClass.new
sc.put_var # 'nil' と印字される

main オブジェクトで定義されたメソッドがどこでも利用できるのは何か特別な処理が行われているのか、それとも Rubyオブジェクトモデルで説明できるものなのか、がよく分かってない。

「トップレベルコンテキストで実行されている = class Object; end の中で実行されている」だから、どこからでも put_var_in_main が利用できるのかな? (そうっぽい)

Rubyで勉強した! - (Lisperp sakuranbo) => t を目指す日記 に書いてある private メソッドとして定義されるというのはどうなんだろう。レシーバを指定しても呼び出せるっぽい。

self # => main
def hoge; puts 'fuga' end
Object.new.hoge # 'fuga' と印字される

あとこの「トップレベルコンテキスト main にメソッドを定義する」(= Object クラスにメソッドを定義する) やり方と、rubygems でやってるように Kernel にメソッドを定義するやり方では何が違うんだろう?

module Kernel

  # 省略 ...
  def gem(gem_name, *version_requirements) # :doc:
    skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
    raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name
    Gem.activate(gem_name, *version_requirements)
  end

  private :gem

end

private にしてるから、'hoge'.gem みたいなことできないのは 1 つの理由として、Object にメソッドを定義するのと Kernel にメソッドを定義するのでは何が違うんだろう? (Object は Kernel をインクルードしてるから結局同じ気がする)

Object.is_a?(Kernel) # => true

2010-10-01

[] オブジェクトを生成したあとでもメソッドを再定義すればオブジェクト内のメソッドは上書きされる 00:43  オブジェクトを生成したあとでもメソッドを再定義すればオブジェクト内のメソッドは上書きされる - 文::字 を含むブックマーク

class Band; def drums; 'Sakura' end end
band = Band.new
p band.drums # "Sakura"
class Band; def drums; 'Ken' end end
p band.drums # "Yukihiro"

メタプログラミング Ruby」読んで分かったけど、オブジェクトインスタンス変数だけ持っててメソッドはクラスを参照しているから、動的にクラスが書き換えられると当然個々のオブジェクトにも反映される。

[] 「メタプログラミング Ruby」メモ 01:22  「メタプログラミング Ruby」メモ - 文::字 を含むブックマーク

module Bird; end
module Beast; end
class Human; end

class Bat
  include Bird
  include Beast
end

class BatMan < Human
  include Beast
  include Bird
end

p Bat.ancestors # => [Bat, Beast, Bird, Object, Kernel]
p BatMan.ancestors # => [BatMan, Bird, Beast, Human, Object, Kernel]
  • Kernel#print がどこからでも使えるのは Object が Kernel をインクルードしているからであり、トップレベルでも print が使えるのはトップレベルが main と呼ばれる Object クラスのインスタンスだから
  • Ruby の private は他の言語とは全く違う動きをする
  • Ruby の private メソッドは自分以外のオブジェクトからは呼び出せず、わざわざ self をつけて呼び出す必要がないため、self をつけて呼び出すとエラーとなる
  • Object#send を使って動的にオブジェクトのメソッドを呼び出すことを「動的ディスパッチ」と呼ぶ
  • rubygemsgem メソッドは Kernel に定義されている
  • OpenStruct
  • パターンディスパッチ (Test::Unit で test_ で始まるメソッドだけをテストとして扱うみたいなやつ)
  • Object#send はプライベートメソッドでも呼び出せる
  • Object#public_send (Ruby 1.9.1)
  • Ruport
  • OpenStruct クラス
  • Delegate ライブラリ
  • respond_to? をオーバーライドしてゴーストメソッドの存在確認ができるようにする
  • Module#const_missing
  • method_missing() とスーパークラスで既に定義されていたメソッドの名前衝突を防ぐ方法、ブランクスレート、Module#undef_method, Module#remove_method
  • ゴーストメソッドはパフォーマンスが悪くなる
  • Builder ライブラリはブランクスレートを使っているので class() 等の Object で定義されているようなメソッドが使える
  • Kernel#local_variables
  • トップレベルのインスタンス変数
  • フラットスコープ
  • 共有スコープ
  • Object#instance_exec (Ruby 1.9)
  • P121 RSpec の例よく分からない
  • Proc <-> ブロックの相互変換 (& つけたり & とったり)
  • lambda と Proc の違い
  • Kernel#proc
    • 1.8 では lambda、1.9 では Proc.new と同じ
  • 矢印ラムダ (->)
  • Object#method, Method#unbind, UnboundMethod, Object#bind
  • Method オブジェクトは Method#to_proc で Procc オブジェクトに変換でき、ブロックは define_method() でメソッドに変換できる
  • [TODO] 自分で書いた RedFlag DSL とサンプルを比較してみる
  • Module#class_eval と object#instance_eval の違い
    • instance_eval は self にのみ変更を加える、class_eval は self とカレントクラスに変更を加える
  • Module#class_eval と class キーワードの違い
  • クラスインスタンス変数とクラス変数の違い
  • クラス変数の癖
    • クラスではなくクラス階層に属していて main オブジェクトで定義すると他のクラスからでも上書きできてしまう
    • このような癖があるためクラス変数よりクラスインスタンス変数のほうが好まれている
  • nil ガード、遅延インスタンス変数
  • P154 deprecate の例
  • 特異クラス
  • [TODO] P167 のロジック理解できない、もう一度読む
  • Object#extend、レシーバの特異クラスにモジュールをインクルードする
  • メソッドの再定義は元のメソッドを変更するのではなく、新しいメソッドを定義して元のメソッドの名前をつけている
    • alias キーワードを使えば再定義前の元のメソッドも呼び出せる
    • これを利用しているのがアラウンドエイリアス (gem の require とか)
  • [TODO] P176 のコード手元の環境で動かなかった、もう一度ちゃんと試す
  • Object#tainted?
  • proc {} call の中でセーフレベル $SAFE を設定してもスコープの外ではもとの値に戻る
  • Merb::Cache::CacheMixin の例、include キーワードインスタンスメソッドではなくクラスメソッドをクラスに登録する
    • Merb::Cache::CacheMixin が included フックメソッドで呼び出し元のクラスの extend メソッドを呼び出すことで実現している (クラス拡張ミックスイン)
  • IDE の管理機能やナビゲーション機能は、その他の冗長な言語には必要だが、Ruby の短くて簡潔なコードには不要なものである」(P216)
  • Kernel#autoload()
  • Object#tap (Ruby 1.9 or Rails が定義)、自己 yield
    • メソッドチェーンの途中でオブジェクトの中身を print したりできる、便利
  • モンキーパッチを見えやすくする
  • ブロックにブロック引数をもたせられるバージョンとそうでないバージョンがあるっぽい
    • {|&block| 'some process' } みたいにできるかどうか
  • private や protected もメソッド (ミミックメソッド)
  • class MyClass < otherclass('test'); end みたいに書くことができる
  • Ruby 1.9 の名前付き引数
    • test(hoge: 'fuga', naha: 'piyo')
  • 同じメソッドでデフォルト値、配列引数、名前付き引数を組み合わせて使う
    • ActiveRecord の find() の例
    • 受け取り側が複雑になる
  • Symbol の Proc 変換
  • eval(), Kernel#binding(), TOPLEVEL_BINDING
  • irb セッションのネスト
  • ActiveRecord::Base は究極のオープンクラス
  • send と __send__ の違い
  • ActiveRecord の中身」あとで読み直す

2010-07-18

[] open-uri の仕組み 23:38  open-uri の仕組み - 文::字 を含むブックマーク

2010-07-17

[] rake -T と desc 23:54  rake -T と desc - 文::字 を含むブックマーク

desc を書かないと rake -T でタスクとして表示されない。

2010-07-13

[][] RSpec 挙動確認 23:36  RSpec 挙動確認 - 文::字 を含むブックマーク

describe 'Array' do
  it {
    Array.stub!(:size).and_return(1)
    [].size.should == 1 # fail
  }
  it {
    array = []
    array.stub!(:size).and_return(1)
    array.size.should == 1 # success
  }
end

前者は Array のクラスメソッド size についてのスタブだから、1 は返ってこない、期待通りの挙動。

ただ、「Array がインスタンス化されて、さらに size というメッセージを受け取ったら、1 を返す」みたいなスタブを作れると便利な気もする。

2010-07-07

[][] 外部からアクセスできない変数をモックにする 21:59  外部からアクセスできない変数をモックにする   - 文::字 を含むブックマーク

他の人のソースをたくさん読んでいるわけではないのでよく使われる方法なのかどうかよく分からないんだけど、Object#instance_variable_get を使えばオブジェクトが持ってるプライベートな変数をばんばんモックにすることができるなと思った。

よくあるスクレイピング用のクラス。

require 'rubygems'
require 'mechanize'

class HatenaDiary

  def initialize(user)
    @user = user
    @agent = WWW::Mechanize.new
  end

  def titles
    @agent.get('http://d.hatena.ne.jp/' + @user + '/archive')
    @agent.page.search('//li[@class="archive archive-section"]/a/text()')
  end

end

こんな感じで使う。

hd = HatenaDiary.new('tily')
puts hd.titles

こういうクラスの場合、WWW::Mechanize をもっと便利に使うラッパーという意味合いが強いので、当然オブジェクトの内部で WWW::Mechanize のメソッドが適切に呼び出されているかをテストしたい。

new したあとで、instance_variable_get('@agent') とかすると普通に HatenaDiary クラス内部にある @agent をモック化できる。

require 'spec'

describe HatenaDiary do

  before do
    @hd = HatenaDiary.new('tily')
    @agent = @hd.instance_variable_get('@agent')
  end

  it '#titles return entry titles' do
    @agent.should_receive(:get).with(
      'http://d.hatena.ne.jp/tily/archive'
    ).once
    @agent.page.should_receive(:search).once.with(
      '//li[@class="archive archive-section"]/a/text()'
    ).and_return('dummy titles')
    ret = @hd.titles
    ret.should == 'dummy titles'
  end

end

2010-07-04

[][] 12:00 2010-07-04 - 文::字 を含むブックマーク

クロージャについては JavaScript のほうがシンプルで好きなんだけど (Ruby は lamda とか Proc とかゴチャゴチャしている印象)、メタプログラミング方面ではやっぱり Ruby のほうが充実しているのかなと思った。

例えばこういうのとか (EeePub のソースより)。SomeClass#some_attr= と SomeClass#some_attr にそれぞれエイリアスを作って、SomeClass#other_attr= と SomeClass#other_attr で set/get できるようにするメソッド。

      def attr_alias(name, src)
        alias_method name, src
        alias_method :"#{name}=", :"#{src}="
      end

この attr_alias のおかげで、EeePub::NCX の doc_title が title という別名でも set/get できるようになって、クラスの外部的なインタフェースが使いやすくなっている。こういうのって、JavaScript 的にはどういう風にやるんだろうな。

2010-07-02

[]Rails メモ 03:37 Rails メモ - 文::字 を含むブックマーク

  • Ajax 用の便利関数
    • link_to_function
    • link_to_remote
    • button_to_remote

2010-01-02

[][]RSpec、describe のネスト 21:13 RSpec、describe のネスト - 文::字 を含むブックマーク

[]Array#compact, Array#compact! 18:52 Array#compact, Array#compact! - 文::字 を含むブックマーク

値が nil の要素を取り除く

2010-01-01

[]可変長引数 01:17 可変長引数 - 文::字 を含むブックマーク

def param_test(must, *rest)
  p rest
end

param_test(1)
param_test(1, 2)
param_Test(1, 2, 3)

結果:

[]
[2]
[2, 3]

2009-12-31

[]バージョン間の違いで結構動かない 22:10 バージョン間の違いで結構動かない - 文::字 を含むブックマーク

開発に使っている MacBook (Ruby v 1.8.6) で作ったものを自宅サーバ (Ruby v 1.8.7) に持って行って動かそうとしたり、

その逆をやったりすると結構動かなかったりする。

移植性をもたせながら作るのは大事だけどいろいろ考慮しなきゃならないのは面倒くさいな。

2009-12-29

[]はてなダイアリー AtomPub API 10:38 はてなダイアリー AtomPub API - 文::字 を含むブックマーク

これ見ながら Ruby で試しに日記を書き込もうとしているんだけどうまくいかない、401 エラーが返ってくる。認証に失敗してるっぽいんだけど、何が悪いのかいまいちよく分からない。

上記ページに載ってる Ruby 用のサンプルコードだとうまく動かなくて、get_service とかやってるところを代わりに手動で collection_uri を作るようにしたらうまく動いた。

require 'rubygems'
require 'atomutil'

username = 'はてなID'
password = 'hatena_password'
auth = Atompub::Auth::Wsse.new :username => username, :password => password
client = Atompub::Client.new :auth => auth
collection_uri = 'http://d.hatena.ne.jp/%s/atom/blog' % username

entry = Atom::Entry.new(
  :title => 'My Entry Title',
  :updated => Time.now
)

entry.content = <<EOF
エントリー本文だよ
EOF

puts client.create_entry collection_uri, entry

下書き投稿とかする場合には HatenaClient クラスを定義する必要があるっぽいけど、今のところ自分は必要としていないので試していない。

あと削除も atomutil - RubyでAtomPubを操作するパッケージをリリースしました - Codin’ In The Free World を見ながらやったらできた。

追記:今試してみたら、はてなダイアリーAtomPubとはに載ってる get_service を使ってるサンプルでも動いた。よく分からない。

2009-12-27

[]do while 23:16 do while - 文::字 を含むブックマーク

begin
  foo
end while condition

ENriqueENrique2013/12/28 22:04It's great to find an expert who can exialpn things so well

SusySusy2013/12/29 15:40This is an <a href="http://lradmx.com">arclite</a> that makes you think "never thought of that!"

2009-12-01

[]サブクラス 動的生成 22:10 サブクラス 動的生成 - 文::字 を含むブックマーク

>> p klass = Class.new(Array)
#<Class:0x1124444>
=> nil
>> Object.const_set('MyArray', klass)
=> MyArray
>> MyArray.new.class
=> MyArray

2009-11-24

[][]Cucumber 実行 オプション 23:34 Cucumber 実行 オプション - 文::字 を含むブックマーク

cucumber -h を実行すればだいたい分かるんだけれどもメモ。

cucumber -l ja
  • 1 フィーチャだけテストしたいとき
    • フィーチャへのパスを指定して実行する
cucumber -l ja features/some_messy.feature
  • 特定のシナリオだけテストしたいとき
    • -n の後に文字列を指定すると、その文字列を名前に含むシナリオだけ実行される
cucumber -l ja -n 文字列
  • タグをつけたシナリオをまとめてテストしたいとき
    • -t のあとにタグ名を指定して実行する
cucumber -l ja -t @some_tag

2009-07-01

[]cgi ライブラリCGI#params で取得される Hash のそれぞれの value には配列が入っている 13:57 cgi ライブラリの CGI#params で取得される Hash のそれぞれの value には配列が入っている - 文::字 を含むブックマーク

2009-06-29

[]Sequel プライマリキーの create / update / delete できない制約を解除 15:04 Sequel プライマリキーの create / update / delete できない制約を解除 - 文::字 を含むブックマーク

2009-06-17

[]クラスメソッド 10:32 クラスメソッド - 文::字 を含むブックマーク

2009-06-13

[]文字列からクラスを生成する 13:31 文字列からクラスを生成する - 文::字 を含むブックマーク

require 'activesupport'
p 'Array'.constantize.class

[]gem 自身のアップデート 13:13 gem 自身のアップデート - 文::字 を含むブックマーク

gem update --system

2009-06-08

[]ファイル ワイルドカードで検索 11:37 ファイル ワイルドカードで検索 - 文::字 を含むブックマーク

  • Dir::glob("/Program Files/*/*.exe") # => Array

2009-05-14

[] 01:45 2009-05-14 - 文::字 を含むブックマーク

  • File::ftype
  • Dir::mkdir
  • File.exist?

2009-05-11

[] 18:28 2009-05-11 - 文::字 を含むブックマーク

8.times { print (rand(94)+32).chr }

2009-05-05

[] 21:59 2009-05-05 - 文::字 を含むブックマーク

  • Integer#step
  • feed-normalizer

2009-05-03

[]inject 22:44 inject - 文::字 を含むブックマーク

FrancescaFrancesca2013/12/29 02:01Exmletery helpful article, please write more.

AntonAnton2013/12/29 15:44Ya learn <a href=\"http://qoyjtdvvk.com\">soinehmtg</a> new everyday. It\'s true I guess!

KaremanKareman2013/12/30 02:47If only there were more cleevr people like you! http://qgcqfqmtz.com [url=http://rhvobgl.com]rhvobgl[/url] [link=http://hkpyaa.com]hkpyaa[/link]

2009-05-01

[]親クラス、先祖クラス群の取得 00:33 親クラス、先祖クラス群の取得 - 文::字 を含むブックマーク

  • Class#superclass, Module#ancestors

2009-04-29

[] 13:15 2009-04-29 - 文::字 を含むブックマーク

  • Hash#sort_by
  • Math.log

2009-04-27

[]正規表現配列、WWW::Mechanize、JSON 15:26 正規表現、配列、WWW::Mechanize、JSON - 文::字 を含むブックマーク

  • 正規表現
    • String#scan で正規表現でグローバルマッチ。Perl の g オプション
    • Array#transpose、何に使うのかと思ってたけど、以下のように scan でグローバルにマッチさせた配列から特定の部分だけ取り出すときに使える
url_regex = /((https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+))/
urls = html.scan(url_regex).transpose[0] 

2009-04-21

[] 22:46 2009-04-21 - 文::字 を含むブックマーク

  • いつも Object#nil? で判定してるのスマートじゃない気がする、他のやり方ないのか

DenzelDenzel2012/06/27 20:34AKAIK you've got the aneswr in one!

dmxzmvddmxzmvd2012/06/28 13:11QyhBNU <a href="http://ywobbcmkctmv.com/">ywobbcmkctmv</a>

zttozynqzttozynq2012/06/28 18:24XVSHLh , [url=http://ienvwodsyclj.com/]ienvwodsyclj[/url], [link=http://smdnpzigxztt.com/]smdnpzigxztt[/link], http://oqlfrjzlkgtm.com/

ctauktpmctauktpm2012/06/29 07:51l4ObcT <a href="http://ccnpqyrsyfkw.com/">ccnpqyrsyfkw</a>

feagxfyfeagxfy2012/07/01 05:005AS9v5 , [url=http://aoftasgimjou.com/]aoftasgimjou[/url], [link=http://bkzetreajjjw.com/]bkzetreajjjw[/link], http://uwqpsibjdqyb.com/

2009-04-12

[]ブロックから抜けるのは next 14:40 ブロックから抜けるのは next - 文::字 を含むブックマーク

[]変数nil かどうか判定する、Object#nil? 09:43 変数が nil かどうか判定する、Object#nil? - 文::字 を含むブックマーク

MarianneMarianne2013/12/17 18:23Towdhcoun! That's a really cool way of putting it!

SharikSharik2013/12/19 06:07If not for your writing this topic could be very <a href="http://bethgela.com">cotelounvd</a> and oblique.

GhamGham2013/12/21 09:56Such an imvrissepe answer! You've beaten us all with that! http://vmutxvyey.com [url=http://waqvot.com]waqvot[/url] [link=http://bycijn.com]bycijn[/link]

2009-02-05

[]ファイルの内容を一気読みする 21:32 ファイルの内容を一気読みする - 文::字 を含むブックマーク

  • all = File.read(filename)

AmmAmm2013/12/28 22:32Great thgknini! That really breaks the mold!

NicoNico2013/12/29 15:40What a <a href="http://canocjbpv.com">plaurese</a> to find someone who thinks through the issues

AnthonyAnthony2013/12/30 02:43That's a genuinely imrpessive answer. http://kijqqhexdz.com [url=http://yztaxdnzc.com]yztaxdnzc[/url] [link=http://gzfsqpxkae.com]gzfsqpxkae[/link]

2009-02-04

[]フィードOPML を作るサンプルコード 18:42 フィード用 OPML を作るサンプルコード - 文::字 を含むブックマーク

require 'rexml/document'

xml = REXML::Document.new
xml << REXML::XMLDecl.new('1.0', 'UTF-8')

opml = xml.add_element('opml', {'version' => '1.0'})
head = opml.add_element('head')
body = opml.add_element('body')
outlines = body.add_element('outline', {'text' => 'Subscriptions'})

1.upto 10 do |i| 
  outlines.add_element('outline', {
    'title'   => i,
    'htmlUrl' => i,
    'text'    => i,
    'type'    => 'rss',
    'xmlUrl'  => i,
  })  
end

xml.write STDOUT

出力

<?xml version='1.0' encoding='UTF-8'?><opml version='1.0'><head/><body><outline text='Subscriptions'><outline title='1' text='1' xmlUrl='1' type='rss' htmlUrl='1'/><outline title='2' text='2' xmlUrl='2' type='rss' htmlUrl='2'/><outline title='3' text='3' xmlUrl='3' type='rss' htmlUrl='3'/><outline title='4' text='4' xmlUrl='4' type='rss' htmlUrl='4'/><outline title='5' text='5' xmlUrl='5' type='rss' htmlUrl='5'/><outline title='6' text='6' xmlUrl='6' type='rss' htmlUrl='6'/><outline title='7' text='7' xmlUrl='7' type='rss' htmlUrl='7'/><outline title='8' text='8' xmlUrl='8' type='rss' htmlUrl='8'/><outline title='9' text='9' xmlUrl='9' type='rss' htmlUrl='9'/><outline title='10' text='10' xmlUrl='10' type='rss' htmlUrl='10'/></outline></body></opml>

[]Twitter で自分が follow してるユーザーの RSSOPML で取得 18:01 Twitter で自分が follow してるユーザーの RSS を OPML で取得 - 文::字 を含むブックマーク

require 'rubygems'
require 'mechanize'
require 'Logger'
require 'rexml/document'

username = ARGV[0]
password = ARGV[1]
log = Logger.new(STDOUT)

log.info("logging in")
agent = WWW::Mechanize.new
agent.get('http://twitter.com/')
agent.page.form_with(:action => 'https://twitter.com/sessions') {|f|
  f.field_with(:name => 'session[username_or_email]').value = username
  f.field_with(:name => 'session[password]').value          = password
  f.click_button
}

users = [] 
page = 1
while 1
  log.info("processing page #{page}")
  agent.get("http://twitter.com/friends?page=#{page}")
  break if agent.page.search('table.doing tr').empty?
  agent.page.search('table.doing tr').each {|user|
    next if(not user.search('img.lock').empty?)
    users.push(
      :name => user.search('td strong a').text,
      :twitter_id   => user.get_attribute('id').sub(/person_(\d+)/, '\\1')
    )
  }
  page = page + 1
end

xml = REXML::Document.new
xml << REXML::XMLDecl.new('1.0', 'UTF-8')
opml = xml.add_element('opml', {'version' => '1.0'})
head = opml.add_element('head')
body = opml.add_element('body')
outlines = body.add_element('outline', {'text' => 'Subscriptions'})

users.each do |user|
  outlines.add_element('outline', {
    'title'   => "Twitter / #{user[:name]}",
    'htmlUrl' => "http://twitter.com/#{user[:name]}",
    'text'    => "Twitter / #{user[:name]}",
    'type'    => 'rss',
    'xmlUrl'  => "http://twitter.com/statuses/user_timeline/#{user[:twitter_id]}.rss",
  })
end

xml.write STDOUT

[]<< って何だっけ文字列連結? 16:51 << って何だっけ文字列連結? - 文::字 を含むブックマーク

2009-02-03

[]Twitter で自分が follow してるユーザーの RSSOPML で取得 00:58 Twitter で自分が follow してるユーザーの RSS を OPML で取得 - 文::字 を含むブックマーク

  • WWW::Mechanize の search メソッドって Hpricot じゃなくて Nokogiri を使っているんだ
  • Nokogiri では search で返ってきた値に対して empty? メソッドを使って空かどうかを判定できる
  • なんか agent.page.search('//table[@class="doing"]/tbody').empty? がページ数が増え続けても true にならないな、と思っていたら tbody は Firebug が付加したやつだった。直で HTML のソース読むようにしなきゃだめだな
  • とりあえず id を取得するところまで書いた。あと少し
username = ARGV[0]
password = ARGV[1]
ids = [] 
log = Logger.new(STDOUT)

log.info("logging in")
agent = WWW::Mechanize.new
agent.get('http://twitter.com/')
agent.page.form_with(:action => 'https://twitter.com/sessions') {|f|
  f.field_with(:name => 'session[username_or_email]').value = username
  f.field_with(:name => 'session[password]').value          = password
  f.click_button
}

page = 1
while 1
  log.info("processing page #{page}")
  agent.get("http://twitter.com/#{username}/friends?page=#{page}")
  break if agent.page.search('//table[@class="doing"]/tr').empty?
  agent.page.links.each {|l|
    if(l.href.match('/direct_messages/create/(\d+)'))
      ids.push($1)
    end
  }
  page = page + 1
end

ids.each do |id|
  p id
end

NathaliaNathalia2012/06/28 19:36Thanky Thanky for all this good inorfmation!

reezqjefmjhreezqjefmjh2012/06/29 05:471AkM10 <a href="http://lmuaunireirl.com/">lmuaunireirl</a>

wiqspytswiqspyts2012/07/01 18:36UfYj8N <a href="http://mvfsjqdgmtki.com/">mvfsjqdgmtki</a>

jphpqrjphpqr2012/07/01 23:42ujTztE , [url=http://nfnovqitwdzb.com/]nfnovqitwdzb[/url], [link=http://uhvddpxxizgz.com/]uhvddpxxizgz[/link], http://nwlmvnpfsump.com/

AjayAjay2013/12/28 21:51d0a0d0b0d0b7d0b1d0b8d0b2d0bad0b0. | d0‘d1‹d1‚d181d1‚d1€d0bed0b9d0bcd0b5d1…. I was recommended this webiste by my cousin. I'm not sure whether this post is written by him as no one else know such detailed about my trouble. You are wonderful! Thanks! your article about d0a0d0b0d0b7d0b1d0b8d0b2d0bad0b0. | d0‘d1‹d1‚d181d1‚d1€d0bed0b9d0bcd0b5d1….Best Regards Cassetta

JaydenJayden2013/12/29 15:40d0a0d0b0d0b7d0b1d0b8d0b2d0bad0b0. | d0‘d1‹d1‚d181d1‚d1€d0bed0b9d0bcd0b5d1…. I was recommended this<a href="http://pabyxe.com"> wteisbe</a> by my cousin. I'm not sure whether this post is written by him as no one else know such detailed about my trouble. You are wonderful! Thanks! your article about d0a0d0b0d0b7d0b1d0b8d0b2d0bad0b0. | d0‘d1‹d1‚d181d1‚d1€d0bed0b9d0bcd0b5d1….Best Regards Cassetta

2009-01-30

[][]pylori*style wiki - RailsでWikiクローンを作る 11:59 [http://tam.qmix.org/wiki/Minki00.html:title=pylori*style wiki - RailsでWikiクローンを作る] - 文::字 を含むブックマーク

MishiMishi2012/06/27 22:50Me dull. You smart. That's just what I nedeed.

uqzuyafznuqzuyafzn2012/06/28 13:27Dw4t6H <a href="http://bjvzwgrcfbou.com/">bjvzwgrcfbou</a>

swygfeswygfe2012/06/29 14:39FJDgWf , [url=http://teuetpfqugge.com/]teuetpfqugge[/url], [link=http://cwpnqmpopdnf.com/]cwpnqmpopdnf[/link], http://lkeytwdlhjgc.com/

tdfoxotdfoxo2012/07/01 00:19mcLMdi <a href="http://xdoutrkpxdhh.com/">xdoutrkpxdhh</a>

wzwmbdwynwzwmbdwyn2012/07/01 05:14oaDRuy , [url=http://vhvldxjwpbxg.com/]vhvldxjwpbxg[/url], [link=http://egayqpmhjlfn.com/]egayqpmhjlfn[/link], http://xbsbduspufhj.com/

2009-01-29

[]Rubyist Magazine - RubyOnRails を使ってみる 【第 3 回】 ActiveRecord 21:06 [http://jp.rubyist.net/magazine/?0006-RubyOnRails:title=Rubyist Magazine - RubyOnRails を使ってみる 【第 3 回】 ActiveRecord] - 文::字 を含むブックマーク

  • ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :dbfile => 'test.db')
    • class User < ActiveRecord::Base end
    • user = User.new; user.name = 'John'; user.occupation = 'Musician'
    • user.save
    • User.find(:all)
  • Class#methods
  • ActiveRecord, find_all とか find_first とかなくなって、ActiveRecord#all とか ActiveRecord#first とかになったのか
  • find のプレースホルダー、? の代わりに名前付きのパラメータを渡すこともできる
  • ActiveRecordMacBook だと /usr/lib/ruby/user-gems/1.8/gems/ にあった
  • よくわからない -「self.append_features(base) は include 時に呼ばれるのでしたね。そして module ClassMethods は base.extend されているので、ここで定義されたメソッドは base (= ActiveRecord::Base) のクラスメソッドとして扱われます。ライブラリを分割する手法として非常に参考になります。」
  • Rails の config/database.yml は establish_connection メソッドに渡すためのデータを定義してたんだ
  • establish_connection で確立した DB 接続は、以降 ActiveRecord::Base.connection で参照できる
  • Test::Unit
  • テーブルが複数形で、それに対応するクラスが単数形
  • :has_many とか :belongs_to とか試す
  • 後半はとりあえずざっと目を通す感じで読んだ

2009-01-28

[]Twitter を使っていろいろやりたい 23:33 Twitter を使っていろいろやりたい - 文::字 を含むブックマーク

2009-01-24

[] 16:20 2009-01-24 - 文::字 を含むブックマーク

[]BookBoard に登録している ASIN のリストを取得して MediaMarker に登録する Ruby プログラム 12:48 BookBoard に登録している ASIN のリストを取得して MediaMarker に登録する Ruby プログラム - 文::字 を含むブックマーク

bb2mm.rb

#!/usr/local/bin/ruby
require 'Bookboard.rb'
require 'MediaMarker.rb'

# get Bookboard username/password
print 'input your Bookboard username:'
uname = $stdin.gets.chop
print 'password:'
system 'stty -echo'
pass = $stdin.gets.chop
system 'stty echo'
print "\n"

asin_list = Array.new
bb = Bookboard.new(uname, pass)
bb.login
0.upto(3) do |num|
  asin_list.concat bb.asin_list_by_cat(num)
end

# get MediaMarker username/password
print 'input your MediaMarker username:'
uname = $stdin.gets.chop
print 'password:'
system 'stty -echo'
pass = $stdin.gets.chop

mm = MediaMarker.new(uname, pass)
mm.login
asin_list.each do |asin|
  mm.register(asin)
end

Bookboard.rb

require 'rubygems'
require 'mechanize'
require 'logger'

class Bookboard
  @uname
  @pass
  @agent
  @log

  def initialize(uname, pass)
    @uname = uname
    @pass  = pass
    @agent = WWW::Mechanize.new
    @log   = Logger.new(STDOUT)
  end

  # log in
  def login
    @log.info("logging in")
    @agent.get('http://www.bookboard.jp/index.php')
    @agent.page.form_with(:method => 'POST') {|f|
      f.field_with('username').value = @uname
      f.field_with('password').value = @pass
      f.click_button
    }
  end

  # get asin list by category
  def asin_list_by_cat(num)
    @log.info('getting asin list by category number');
    asin_list = Array.new
    @agent.get("http://www.bookboard.jp/index.php?categori=#{num}")
    @agent.page.links_with(:href => /asin=/).each do |link|
      asin_list.push link.href.match(/asin=([0-9A-Z]+)/)[1]
    end
    return asin_list
  end
end

MediaMarker.rb

require 'rubygems'
require 'mechanize'
require 'logger'

class MediaMarker
  @agent
  @uname
  @pass
  @log

  def initialize(uname, pass)
    @agent = WWW::Mechanize.new
    @uname = uname
    @pass  = pass
    @log   = Logger.new(STDOUT)
  end

  # log in
  def login
    @log.info('logging in')
    @agent.get('http://mediamarker.net/login')
    @agent.page.form_with(:name => 'login'){|f|
      f.field_with(:name => 'uname').value = @uname
      f.field_with(:name => 'pass').value = @pass
      f.click_button
    }
    # todo: login failure process
  end
  
  # register asin
  def register(asin)
    @log.info("registering asin: #{asin}")
    @agent.get("http://mediamarker.net/reg?cat=1&asin=#{asin}")
    @agent.page.form_with(:name => 'reg'){|f| 
      f.click_button
    }
  end
end

2009-01-20

[]no title 00:02 [http://www.ruby-lang.org/ja/man/html/Regexp.html#match:title] - 文::字 を含むブックマーク

[]プログラミング Ruby - 第 22 章 Ruby の文法 22:47 プログラミング Ruby - 第 22 章 Ruby の文法 - 文::字 を含むブックマーク

2009-01-16

[]no title 04:38 [http://doruby.kbmj.com/akio0911_on_rails/20081219/Rails___MeCab___Twitter__:title] - 文::字 を含むブックマーク

[][]Entry is not found - hitode909の日記 04:38 [http://d.hatena.ne.jp/hitode909/20080124/1201144244:title] - 文::字 を含むブックマーク