2016-11-11 42 views
2

如何在普通ruby文件的主要绑定中定义变量?如何在主要动态创建局部变量

我已经试过TOPLEVEL_BINDING,但不要共享变量范围主要

#!/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不能动态创建局部变量。 (它可以在v1.8中用'eval'完成。) –

+0

@spickermann希望我的代码类似rspec) – bjornmelgaard

回答

1

您可以定义动态的实例变量:

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

我不认为没有明确使用绑定是可能的。问题也在于你是否应该这样做;) –