使用块变量访问Ruby访问器

时间:2010-01-22 14:09:23

标签: ruby sinatra

我有一个应用程序,我使用Active Record来访问数据库。我正在尝试获取信息并将其放入哈希值以供以后使用。

这基本上就是我在做什么。

require 'active_support'
    @emailhash = Hash.new
    emails = Email.find(:all)
    emails.each do |email|
            email.attributes.keys.each do |@column|
                    @emailhash[email.ticketno] || Hash.new
                    @emailhash[email.ticketno] = email.@column
            end
    end

不起作用的行是:

@emailhash[email.ticketno] = email.@column

有什么方法可以做到这一点吗?基本上我的目标是建立一个存储在表列中的值的哈希值,欣赏任何输入。

4 个答案:

答案 0 :(得分:3)

  • Ruby程序员通常缩进2
  • 您的代码将所有电子邮件压缩成一个哈希条目,而不是每个电子邮件的条目。
  • 如果要动态调用方法,请使用Object.send
  • @emailhash[email.ticketno] || Hash.new没有做任何事。

这样的事可能会这样做:

require 'active_support'
@emailhash = {}
Email.find(:all).each do |email|
  @mailhash[email.ticketno] = {}
  email.attributes.keys.each do |key|
    @emailhash[email.ticketno][key] = email.send(key)
  end
end

关键部分是“发送”,它调用由字符串或符号标识的方法。

答案 1 :(得分:2)

你不能以@开头的迭代器变量。尝试这样的事情:

require 'active_support'
@emailhash = Hash.new
emails = Email.find(:all)
emails.each do |email|
        @emailhash[email.ticketno] = email.attributes.keys.collect{|key| key.column}
end

答案 2 :(得分:1)

除了blinry的评论,该行

@emailhash[email.ticketno] || Hash.new

看起来很可疑。你确定你不想要

@emailhash[email.ticketno] ||= Hash.new

答案 3 :(得分:0)

除了之前的准确观察,我想补充以下内容:

第1点。
重要的是要声明@ivars可能不适用于正式的函数参数...这就是说,我认为它是无效的:

collection.each { |@not_valid| }

在块内部使用@ivars也是一种不好的做法,您不会确定该块将在哪个上下文中执行(众所周知,该块内的self引用可能与其外的self引用不同。)

第2点。
您应该记住的另一点是,如果您不指定(||)运算符的结果,则根本不会进行任何修改(只是浪费时间),但您可以使用:

mail_hash[email.ticketno] = mail_hash[email.ticketno] || Hash.new

这很容易改写为:

mail_hash[email.ticketno] ||= Hash.new

第3点。
即使email.attributes.keys是一个廉价的指令,也不是免费的......我建议在迭代块之外有这个(假设我们没有使用文档数据库,每个记录的密钥总是相同的) 。

最终结果

require 'active_support'

mails = Email.all
@mailshash = mails.inject(Hash.new) do |hsh, mail|
  # mail.attributes is already a representation of the 
  # email record in a hash
  hsh[mail.ticketno] = mail.attributes
  hsh
end