将字符串转换为类

时间:2013-11-16 10:30:09

标签: ruby metaprogramming

我需要的是:

我传递了一个必须在数组中设置不可变对象的字符串,但我不知道如何从用户输入的字符串转换到我需要的对象名称。

我打算做什么:

我正在进行一次对话冒险。关键是要有一个创建命令提示符的功能,以便用户可以与游戏进行交互。每当用户说“去某个地方”时,还有另一个叫做“goto”的功能,它比较输入是否包含在玩家所在地的出口;如果是这样,玩家的属性“地点”将占据新的位置。

我做了什么:

我做了一个实际有效的命令提示符*

loop do 
        print "\n >>> "
        input = gets.chomp
        sentence = input.split

        case
        when sentence[0] == "inspect"
                $action.inspect(sentence[1])
            when sentence[0] == "go" && sentence[1] == "to"
                $action.goto(sentence[2])
            when sentence[0] == "quit"
                break
            else
                puts "\nNo le entiendo Senor..."
        end

我根据需要初始化对象(第三个属性用于退出):

room = Place.new("room", "Room", [newroom], "This is a blank room. You can _inspect_ the -clock- or go to [newroom].", ["this this"])
newroom = Place.new("newroom", "New Room", [room], "This is another blank room. You can _inspect_ the -clock-", ["this this"])

然后我在动作控制器内部创建了一个方法,该方法必须正确地比较和设置位置。 (注意:跟随怪物新手代码。保护你的眼睛)。

def goto(destiny) #trying to translate the commands into variable names
    if (send "#{destiny}").is_in? $player.place.exits
        $player.place = send "#{sentence[2]}"
        puts destiny.description
    else
        puts "I cannot go there."
    end
end

2 个答案:

答案 0 :(得分:2)

我认为您希望将字符串转换为常量。嗯,这很容易。阅读一个例子:

string = 'Hash'
const = Object.const_get(string) #=> Hash
const.new #=> {}; <- it is an empty Hash!

但要小心。如果没有这样的常数,你将得到未初始化的常量错误。在这种情况下,你的冒险将停止。

我希望我理解你的问题,你会理解我的答案。

答案 1 :(得分:1)

如何将字符串更改为对象,选项很少:

Bad(eval family):

eval("name_of_your_variable = #{21+21}")
eval("puts name_of_your_variable") #42

您可以看到eval可以使所有内容。所以要谨慎使用。

但是,正如@ user2422869指出的那样,你需要(进入)范围 - 你的变量已保存的地方。所以上面的代码不会在任何地方运行

每次运行以下方法时,都会创建另一个范围

def meth1
  puts "defined: #{(defined? local_a) ? 'yes' : 'no'}!"
  eval 'local_a = 42'
  local_a += 100
  eval 'puts local_a'
end

meth1

这是输出:

  

定义:不!   142

如果您想从local_a的一个范围中抓取meth1,则需要绑定。

def meth2
  var_a = 222
  binding
end

bin = meth2

bin.eval 'var_a'

#output:
#222

关于绑定,您可以阅读doc。至于范围,我没有好的网站。

更好的:

hash_variable = Hash.new # or just {}
hash[your_string_goes_here] = "some value #{42}"
puts hash[your_string_goes_here]

我不知道好坏:

至于此:send "#{destiny}"。我假设您的destiny不存在,因此您可以使用method_missing

def method_missing arg, *args, &block
  #do some with "destiny"; save into variable/hash, check if "destiny" is in right place etc.
  # return something
end