2017-09-09 53 views
-1

我試圖編寫一個實用程序庫,它試圖調用任意對象類型的方法。在Ruby中,我會做一些事情,如:未知類型的方法參數

def foo(object) 
    object.public_send(:bar) 
rescue NoMethodError 
    raise "Method not defined on object" 
end 

foo(instance_of_my_arbitrary_class) 

我不知道如何在水晶做到這一點,因爲我們的類型未知,所以我得到的Can't infer the type of instance variable 'object'編譯錯誤。

如何在不知道要傳遞的對象類型的情況下完成此操作?

+0

您是否正在設計一個抽象類? –

+1

@MarkThomas也許?只是學習,讓我看看抽象類。 –

+0

這是Crystal中的[已知限制](https://github.com/crystal-lang/crystal/issues/2733)。可能你可以使用[泛型]實現這個(https://crystal-lang.org/docs/syntax_and_semantics/generics.html) –

回答

1

我想通過利用一個模塊並將其包括在內,我想到了這一點。

module ArbitraryObject; end 

class Arbitrary 
    include ArbitraryObject 
end 

class MyLib 
    def foo(object : ArbitraryObject) 
    ... Code here ... 
    end 
end 

MyLib.new(Arbitrary.new).foo 
1

在Crystal中,您不能在任意對象上調用任意方法,因爲方法在編譯時解析,而不是運行時解析。如果用戶試圖用不兼容的類型使用庫的方法,他將得到一個編譯時錯誤:

def foo(object) 
    object.bar 
end 

class MyObj 
    def bar 
    puts "bar!" 
    end 
end 

foo(MyObj.new) # => "bar!" 

這工作,作爲MyObj一個實例具有方法bar。但是,如果你使用的東西,沒有這樣的方法,用戶將得到一個編譯時錯誤:

foo(3) # compile error: undefined method 'bar' for Int32 

這個錯誤會在程序執行之前showned。