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の既存のインスタンスを参照するように文字列を変換する方法を理解できませんでしたlounge

4

5 に答える 5

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 に答える
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
  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 に答える
0

メソッドを使用evalして、rubyスクリプトの一部を動的に実行できます。この場合eval(room)、部屋のインスタンスが表示されます。

ただし、これはエンドユーザーがコードを実行できるため、非常に危険な方法です。コードの実行から保護するには、それが定義された部屋変数の1つであることを確認することをお勧めします。

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 に答える