从proc声明时从def访问变量

时间:2013-08-11 18:14:12

标签: ruby scope sinatra

我有这样的事情:

@menus = { Yay: '/', Yay2: '/yay2' }

@menus.each do |title, link|
  get link do
    erb title.downcase
  end
end

def foo
  'test' + @menus.join(', ')
end

yay.erb或yay2.erb包含:

<%= foo %>

它显示@menus中的方法foonil对象的错误,因为在proc中声明了get link,如何克服这个问题?

2 个答案:

答案 0 :(得分:3)

问题是@menus有一个类的实例变量,而在方法中它指的是实例的实例变量 - 它是不同的。

@menus设为局部变量,以便将其关闭,然后使用define_method代替def,这样您的方法定义就是一个闭包,menus可以从中获取:

menus = { Yay: '/', Yay2: '/yay2' }

menus.each do |title,link|
  get link do
    erb title.downcase
  end
end

define_method :foo do
  'test' + menus.join(', ')
end

答案 1 :(得分:0)

1)哈希没有join()方法。

2)显然你发布的代码在一个类中,所以另一种解决方案是为你创建的名为@menus的类实例变量提供一个访问器方法,然后代替编写@menus会写self.class.menus:

class SomeClass
  #Inside here and outside of any def's self=SomeClass

  class <<self           #Open the class's singleton class
    attr_reader :menus
  end

  @menus = { Yay: '/', Yay2: '/yay2' }  #@menus attaches to self, which is SomeClass

  @menus.each do |title, link|  #@menus is retrieved from whatever object self is, which is SomeClass
    puts title, link
  end

  def foo
     #Inside here self=the instance of SomeClass that called this method, 
     #so @menus will be retrieved from that instance--not SomeClass
    'test ' + self.class.menus.keys.join(', ')
  end

end

实例变量,即那些以@开头的变量,将自己附加到任何自我或从自己的任何东西中检索出来。