2016-11-11 9 views
2

プレーンなルビファイルのメインバインドで変数を定義する方法は?メインでローカル変数を動的に作成するには

私はそのいけないのシェア変数がメインスコープに

#!/usr/bin/env ruby 
# .... 

5.times do |i| 
    src = %(
    reader#{i} = library.create_reader "name" 
    book#{i} = library.create_book "title" 
) 
    TOPLEVEL_BINDING.eval(src) 
end 

3.times { reader0.take(book0) } # error 
5.times { reader1.take(book1) } 
1.times { reader2.take(book2) } 
0.times { reader3.take(book3) } 
1.times { reader4.take(book4) } 

puts book0.title 
+3

私はなぜそれをしたいのだろうか?配列やハッシュを使ってオブジェクトを格納し読み込むのは簡単ではないでしょうか? – spickermann

+1

Ruby v1.8以降、ローカル変数を動的に作成することはできませんでした。 (これは 'eval'でv1.8で行うことができます) –

+0

@spickermannは私のコードをrspecに似せています) – bjornmelgaard

答えて

1

をTOPLEVEL_BINDINGを試してみましたが、しているあなたは、動的にインスタンス変数を定義することができます。

5.times do |i| 
    instance_variable_set(:"@reader#{i}", "library_name#{i}") 
    instance_variable_set(:"@book#{i}", "book_title#{i}") 
end 

puts @reader1 
puts @book1 
puts @book4 

# => library_name1 
# book_title1 
# book_title4 

を別の可能性は、偽のローカル変数にmethod_missingを使用することであろう、インスタンス変数をキャッシュとして使用する場合:

def create_variable_or_use_cache(name, &block) 
    name = "@#{name}" 
    instance_variable_get(name) || instance_variable_set(name, block.yield) 
end 

def method_missing(sym,*p) 
    if sym=~/^reader(\d+)$/ then 
    create_variable_or_use_cache(sym){ "Create reader#{$1} here" } 
    elsif sym=~/^book(\d+)$/ then 
    create_variable_or_use_cache(sym){ "Create book#{$1} here" } 
    else 
    super 
    end 
end 

puts reader1 
puts reader1 
puts book3 
wrong_method 

# => 
# Create reader1 here 
# Create reader1 here 
# Create book3 here 
# binding.rb:13:in `method_missing': undefined local variable or method `wrong_method' for main:Object (NameError) 

それは面白いRubyのエクササイズですが、私はあなたがそれを使うべきかどうか確信していません。

+0

はい、私はそれも考えましたが、私はローカルとしたいです – bjornmelgaard

+0

明白にバインディングを使用せずに可能ではないと思います。あなたがそれをするべきかどうかの質問もあります;) –

関連する問題