3

给定一个类实例和一个字符串,如何将字符串转换为引用该实例?

class Room
  def enter
    puts "Welcome!"
  end
end

# Rooms are predefined
lounge = Room.new
kitchen = Room.new
study = Room.new

puts "Which room would you like to go to?"
print "> "
room = gets.strip

# User types "lounge"

room.enter # => undefined method `enter' for "lounge":String (NoMethodError)

我理解为什么我会收到 NoMethodError,但我无法弄清楚如何将room字符串转换为引用 Room 的现有实例 named lounge

4

5 回答 5

1
class Room
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def enter
    puts "Welcome to #{@name}!"
  end
end

# Rooms are predefined
rooms = ["lounge", "kitchen", "study"].map(&Room.method(:new))

puts "Which room would you like to go to?"
print "> "
name = gets.strip

# Just an example (not using find to avoid nil.enter)
p rooms.select{ |room| room.name == name }.map(&:enter)
于 2012-10-23T16:55:28.510 回答
1
room_name = gets.strip.capitalize
room = Kernel.const_get(room_name)
room.enter

如果您require "active_support/all"(Rails 的一部分)可以这样做:

room = gets.strip.camelize.constantize
room.new.enter

编辑:

正如铁皮人指出的那样,require "active_support/core_ext/string/inflections"效率会更高。

于 2012-10-23T16:04:59.977 回答
1

也许试图映射房间并通过密钥获取它们?

class Room

  def enter
    puts "Welcome!"
  end
end

# Rooms are predefined
rooms = %w[lounge kitchen study].inject({}) { |f,c| f.update c => Room.new }

puts "Which room would you like to go to?"
print "> "
if room = rooms[gets.strip]
  room.enter
end

或者更简单:

class Room

  def initialize room_type
    @room_type = room_type
  end

  def enter
    return puts 'Unsupported room type' unless %w[
      lounge kitchen study
    ].include?(@room_type)
    puts "Welcome to #{@room_type}!"
  end

end

puts "Which room would you like to go to?"
print "> "
room = Room.new(gets.strip)
room.enter
于 2012-10-23T16:01:18.807 回答
0

您可以使用eval方法来动态执行一段 ruby​​ 脚本。在这种情况下eval(room)会给你房间实例。

然而,这是一种非常危险的方法,因为它允许最终用户执行代码。为了防止代码执行,您最好验证它是定义的房间变量之一:

eval(room).enter if local_variables.include?(room.to_sym)
于 2012-10-23T16:01:30.260 回答
0

我最终在初始化时将每个 Room 对象作为类变量存储在哈希中。这使您可以通过哈希引用每个实例:

class Room
  @@rooms = {}

  def initialize(name)
    @@rooms.store name, self
  end

  def rooms
    @@rooms
  end

  def enter
    puts "Welcome!"
  end
end

# Rooms are predefined
lounge = Room.new('lounge')
kitchen = Room.new('kitchen')
study = Room.new('study')

puts "Which room would you like to go to?"
print "> "
new_room = gets.strip

lounge.rooms[new_room].enter if lounge.rooms.has_key? new_room
于 2012-10-24T06:47:08.640 回答