2017-12-26 6 views
2

プログラムはタイプPosition => LivingBeing | Thinggridと呼ばれるハッシュの要素を記憶しています。このgridMapに保存されていると私は、このMapThingのサブクラスであるクラスAppleの要素の位置を返すようにしたいと思います。"実際の"クラスでインスタンス変数を見つけるにはどうすればよいですか?私が書いている

しかし、クラスを取得するためにtypeof()を使用しているとき、私は代わりに、サブクラスのLivingBeing | Thingを得る。ここApple

Mapクラスです:

ここ
class Map 
    @@grid = {} of Position => LivingBeing | Thing 

    def initialize() 
    end 

    # Add an entity to the grid 
    def add_entity(new_entity : LivingBeing | Thing) 
    @@grid[new_entity.position] = new_entity 
    end 

    # Return the position of an object of class "something" 
    def self.where_is?(something : Class) 
    # First attempt was to get the key by the value 
    # @@grid.key(something) 

    @@grid.each do |position, thing| 
     # Returns "thing #<Apple:0x55f1772085c0> at Position(@x=1, @y=2) is (LivingBeing | Thing)" 
     puts "thing #{thing} at #{position} is #{typeof(thing)}" 
     position if typeof(thing) == something 
    end 
    end 

Thingクラス:

abstract class Thing 
    getter position 
    @name = "Unkown object" 

    def initialize(@position : Position) 
    end 
end 

class Apple < Thing 
    @name = "Apple" 
end 

ここにはPosition構造体:

struct Position 
    getter x, y 

    def initialize(@x : Int32, @y : Int32) 
    end 
end 

そして、ここでは、私はそれを渡すようにしようテストです:

it "gives a random thing location based on its class" do 
    world = Map.new() 
    apple = Apple.new(Position.new(1, 2)) 
    puts "Apple type : #{typeof(apple)}" # Returns "Apple type : Apple" 
    world.add_entity(apple) 
    position = Map.where_is?(Apple) 
    position.should eq Position.new(1, 2) 
end 

Appleクラスを与えることができるいくつかのクラスメソッドや関数はありますか? それはデザイン上の問題ですか?

は、あなたの答えをありがとう!私が持っている

+1

あなたのコードをコンパイルするのに 'Position'が必要ですが、' thing.is_aならpositionを返しますか?何かがあなたの問題を解決する? 'typeof(foo)'はコンパイル時の型を返しますが、 'foo.is_a?'と 'foo.class'は実行時に動作します。 – RX14

+0

コードをコンパイルする場合は、私の質問を更新して 'Position'を追加しました。私は 'positionof thing.is_a(something) 'と' typeof(thing)== something'の位置を置き換えようとしましたが、このエラーが発生します: '' CONST' – KillianKemps

答えて

1

あなたがこの問題を解決するためにforallを使用することができます。

forall Tを使用して導入された)型変数TT.class型制限に一致する定数Appleに通過するAppleであると推測することができるからである。この作品Tは、is_a?で使用できる定数です。

1

一つの解決策は、私の機能のために、このです:

テスト用
# Return the position of an object of class "something" 
    def self.where_is?(something) 
    @@grid.each do |position, thing| 
     return position if thing.is_a?(typeof(something)) 
    end 
    end 

そして、この:

it "gives a random thing location" do 
    world = Map.new(4) 
    apple = Apple.new(Position.new(1, 2)) 
    world.add_entity(apple) 
    position = Map.where_is?(Apple.new(Position.new(0, 0))) 
    position.should eq Position.new(1, 2) 
    end 

他の解決策が存在しない場合、私はこのようにそれを使用します。しかし、私はRX14が言った@、それはあなたのように見えるとして、私が代わりに position = Map.where_is?(Apple.new(Position.new(0, 0)))

0

position = Map.where_is?(Apple)を行うことができるようにしたいと思いApple

のインスタンスを作成するのではなく、直接クラスAppleを検索することができることを好むだろう実行時の "タイプ"を確認したい、つまり.class。ここでは例を示します。

# Return the position of an object of class "something" 
    def self.where_is?(something : T.class) forall T 
    @@grid.each do |position, thing| 
     return position if thing.is_a?(T) 
    end 
    end 

をし、あなたが望むだけのようMap.where_is? Appleを使用してそれを呼び出す:

class Apple 
    @name = "Apple" 
end 

def check(obj : Object) 
    obj.class == Apple 
end 

a=Apple.new 
p check(a) 
関連する問題