【问题标题】:Dynamic Constant Assignment Error [duplicate]动态常数分配错误 [重复]
【发布时间】:2013-04-04 09:42:19
【问题描述】:

我正在执行一个查询并尝试将其存储在一个常量中,该常量工作正常,直到我今天对源文件进行了更改,但这让我感到困惑,因为我没有更改查询或更改任何交互的代码用这个查询。

代码如下:

require 'rexml/document'
include REXML

def parallel_sort(data, labels)
    #implement a basic ruby styled selection sort in to sort the data in descending order
    raise "unequal arrays" if  data.length != labels.length

    0.upto(data.length - 2) do |i|
        max = i # largest value
        (i+1).upto(data.length - 1) { |j| max = j if data[j] > data[max] } #try to find new max
        data[i], data[max], labels[i], labels[max] = data[max], data[i], labels[max], labels[i] if i != max #swap values in both arrays
    end

    return (data, labels)
end

def process_xml_files(filenames)
    builds = ["Total Builds", "Failed Builds", "Successful Builds"]
    outFile = File.new("gchart-data.txt", "w")
    #outFile = File.new("parallel_sort_test.txt", "w")
    yearly_data    = []
    yearly_labels  = []
    monthly_data   = []
    monthly_labels = []
    failure_data   = []
    failure_labels = []
    failure_percents = []
    hash = []

    #retrieve needed data from the XML file
    filenames.each do |filename|
        #create a document
         doc = Document.new(File.new(filename))
         doc.elements.each("//row/field") do |e|
         name = e.attributes['name']
         text = e.text

         #search for tags and append correct data to lists
         if builds.include?(name)
            hash.push(name)
            hash.push(text)
         else
            if name == "Month-Year"
                yearly_labels.push(text)
            elsif name == "Past-Year-Builds"
                yearly_data.push(text)
            elsif name == "Month-Day"
                monthly_labels.push(text)
            elsif name == "Past-Month-Builds"
                monthly_data.push(text)
            elsif name == "Failure Type"
                failure_labels.push(text)
            else 
                temp = 100*(text.to_f() / FAILED_BUILDS.to_f())
                failure_data.push(temp)
                failure_percents.push(((100*temp).round/100.0).to_s() + "%")
            end
        end
        end
    end 

    #sort the failure_percents and failure_labels arrays together
    failure_percents, failure_labels = parallel_sort(failure_percents, failure_labels)

    outFile.puts hash
    outFile.puts "\nYearly Data\n#{yearly_data.join(",")}"
    outFile.puts yearly_labels
    outFile.puts "\nMonthly Data\n#{monthly_data.join(",")}"
    outFile.puts monthly_labels
    outFile.puts "\nFailure Data\n#{failure_data.join(",")}"
    outFile.puts failure_labels.zip(failure_percents).join("|") 
end

def execute_queries()
    FAILED_BUILDS = `mysql -h hostname -u root -D database -e 
    "SELECT COUNT(id) FROM builds WHERE buildstatus = 3 
    AND DATE(submittime) >= 
    DATE_SUB(CURDATE(), INTERVAL 1 YEAR);"`.gsub!(/[A-Za-z()\s]+/,"")

    #get the total number of builds
    totalBuilds = `mysql -h hostname -u root -D database  -X -e 
    "SELECT COUNT(buildid) 'Total Builds' FROM builds 
    WHERE DATE(submittime) >= 
    DATE_SUB(CURDATE(), INTERVAL 1 YEAR);" > total-builds.xml`

    #get the number of successful builds
    successBuilds = `mysql -h hostname -u root -D database -X -e 
    "SELECT COUNT(buildid) 'Successful Builds' FROM builds 
    WHERE buildstatus = 2 AND DATE(submittime) >= 
    DATE_SUB(CURDATE(), INTERVAL 1 YEAR);" > success-builds.xml`

    #get the number of failed builds 
    failedBuilds = `mysql -h hostname -u root -D database -X -e 
    "SELECT COUNT(buildid)'Failed Builds' FROM builds 
    WHERE buildstatus = 3 AND DATE(submittime) >= 
    DATE_SUB(CURDATE(), INTERVAL 1 YEAR);" > failed-builds.xml`

    #get the number of builds per month
    months = `mysql -h hostname -u root -D database -X -e 
    "select count(id) as 'Past-Year-Builds', 
    CONCAT(SUBSTR(MONTHNAME(submittime), 1,3), '-',
    YEAR(submittime)) as 'Month-Year' from builds where 
    DATE(submittime) >= DATE_SUB(CURDATE(), interval 1 year)
    group by YEAR(submittime), MONTH(submittime);" > year-builds.xml`

    days = `mysql -h hostname -u root -D database -X -e 
    "SELECT COUNT(id) AS 'Past-Month-Builds', 
    CONCAT(SUBSTR(MONTHNAME(submittime), 1, 3), '-', 
    DAY(submittime)) as 'Month-Day' FROM builds
    WHERE DATE(submittime) >= DATE_SUB(CURDATE(), INTERVAL 30 day) 
    GROUP BY MONTH(submittime), DAY(submittime);" > month-builds.xml`

    failures = `mysql -h hostname -u root -D database -X -e 
    "select F.name 'Failure Type', count(B.id) 'Failure Count' 
    from builds B JOIN failureareas F ON B.failurearea = F.id 
    where Date(B.submittime) >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR) 
    AND B.buildstatus != 2 GROUP BY F.name;" > failures.xml`
end


def start()
    #grab data from the database
    execute_queries()

    #collect the xml files from the current directory
    filenames = Dir.glob("*.xml")

    #merge the xml files together
    finalXML = process_xml_files( filenames )

    #clean up directory 
    filenames.each do |filename|
        del = `rm #{filename}`
    end
end

#test for execution
if __FILE__ == $0
    start()
end

那么谁能告诉我为什么这不起作用?我只分配给常量一次。

这是错误:

gchart-url.rb:14: syntax error
gchart-url.rb:75: dynamic constant assignment
    FAILED_BUILDS = `mysql -h hostname -u root -D database -e 
    "SELECT COUNT(id) FROM builds WHERE buildstatus = 3 
    AND DATE(submittime) >= 
    DATE_SUB(CURDATE(), INTERVAL 1 YEAR);"`.gsub!(/[A-Za-z()\s]+/,"")
                   ^
gchart-url.rb:114: syntax error

任何帮助都会很棒。 谢谢。

编辑:对不起,很长的帖子

【问题讨论】:

  • working fine until I made a change 究竟发生了什么变化?
  • 我在文件顶部添加了parallel_sort方法。

标签: ruby


【解决方案1】:

首先,您应该整理语法错误,从第一个报告的错误开始 - 通常其余的都会消失。

在第 14 行更改 return 以返回一个数组:

  return [data, labels]
end

Ruby 认为您不应该从方法中设置常量。从类定义(在任何“def”块之外)设置它不会是错误的。如果你真的想从一个方法创建一个常量,使用这个:

self.class.const_set(:FAILED_BUILDS, `mysql -h ....

但我的问题是:为什么要设置一个常数?实例变量可能是更好的解决方案。

【讨论】:

  • 谢谢。执行查询后,我从数据中提取一个数字并使用它来执行操作。这个数字在程序运行期间永远不会改变,这就是常量背后的原因。
  • 我会说,即使在这种情况下,变量会更好。常量是在源代码中设置的东西——比如 PI 的值或配置文件的默认位置,但程序计算的任何东西都是变量——即使它只计算一次。这只是我的谦虚建议;-)
  • 它可能很有用,例如如果您想测试一个具有上限但不想迭代直到达到限制的对象(现实世界限制:5000,测试限制:3)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 2014-02-23
  • 2018-10-01
  • 1970-01-01
相关资源
最近更新 更多