5

这是一个新手问题,因为我正在尝试自己学习 Ruby,如果这听起来像一个愚蠢的问题,请道歉!

我正在阅读为什么(辛酸)指南的示例,并在第 4 章中。我将 code_words 哈希输入到一个名为 wordlist.rb 的文件中

我打开了另一个文件并输入了第一行作为 require 'wordlist.rb' 和其余代码如下

#Get evil idea and swap in code
print "Enter your ideas "
idea = gets
code_words.each do |real, code|
    idea.gsub!(real, code)
end

#Save the gibberish to a new file
print "File encoded, please enter a name to save the file"
ideas_name = gets.strip
File::open( 'idea-' + ideas_name + '.txt', 'w' ) do |f|
    f << idea
end

当我执行此代码时,它失败并显示以下错误消息:

C:/MyCode/MyRubyCode/filecoder.rb:5: main:Object (NameError) 的未定义局部变量或方法“code_words”

我使用 Windows XP 和 Ruby 版本 ruby​​ 1.8.6

我知道我应该设置类似 ClassPath 的东西,但不确定在哪里/如何设置!

提前谢谢了!

4

5 回答 5

5

虽然所有文件的顶层都在相同的上下文中执行,但每个文件都有自己的局部变量脚本上下文。换句话说,每个文件都有自己的一组局部变量,可以在整个文件中访问,但不能在其他文件中访问。

另一方面,常量(CodeWords)、全局变量($code_words)和方法(def code_words)可以跨文件访问。

一些解决方案:

CodeWords = {:real => "code"}

$code_words = {:real => "code"}

def code_words
  {:real => "code"}
end

对于这种情况,一个 OO 解决方案绝对过于复杂:

# first file
class CodeWords
  DEFAULT = {:real => "code"}

  attr_reader :words
  def initialize(words = nil)
    @words = words || DEFAULT
  end
end

# second file
print "Enter your ideas "
idea = gets
code_words = CodeWords.new
code_words.words.each do |real, code|
  idea.gsub!(real, code)
end

#Save the gibberish to a new file
print "File encoded, please enter a name to save the file"
ideas_name = gets.strip
File::open( 'idea-' + ideas_name + '.txt', 'w' ) do |f|
  f << idea
end
于 2009-06-30T00:49:32.797 回答
1

我认为问题可能是 require 在另一个上下文中执行代码,因此运行时变量在 require 之后不再可用。

您可以尝试将其设为常数:

CodeWords = { :real => 'code' }

这将无处不在。

是关于变量范围等的一些背景知识。

于 2009-06-30T00:07:47.030 回答
1

我只是在看同一个例子并且遇到了同样的问题。我所做的是将两个文件中的变量名从 更改code_words$code_words.

这将使它成为一个全局变量,因此两个文件都可以访问它吗?

我的问题是:这不是一个比使其成为常数并必须编写更简单的解决方案,CodeWords = { :real => 'code' }还是有理由不这样做?

于 2013-01-16T00:19:27.930 回答
0

更简单的方法是使用 Marshal.dump 功能来保存代码字。

# Save to File
code_words = {

'starmonkeys' => 'Phil 和 Pete,新帝国的那些棘手的总理','catapult' => 'chucky go-go','firebomb' => '热辅助生活','Nigeria' => "Ny和杰瑞的干洗店(带甜甜圈)”,“把卡波什放在上面”=>“把有线电视盒放在上面”}

# Serialize
f = File.open('codewords','w')
  Marshal.dump(code_words, f)
f.close

现在在你的文件的开头你会放这个:

# Load the Serialized Data
code_words = Marshal.load(File.open('codewords','r'))
于 2009-07-03T22:49:18.750 回答
0

这是确保您始终可以包含与您的应用程序位于同一目录中的文件的简单方法,将其放在 require 语句之前

$:.unshift File.dirname(__FILE__)

$: 是代表“CLASSPATH”的全局变量

于 2009-07-03T23:12:41.340 回答