これは興味深い質問です。重要な問題は、宣言された型として何を定義するかです。::SomeType
すべてのメソッド定義にステートメントがあることを意味する場合、Juliaで動的コード生成のさまざまな可能性があるため、実行するのはやや難しいです。この意味で完全な解決策があるかもしれませんが、私はそれを知りません(私はそれを学びたいと思います)。
しかし、私の頭に浮かぶのは、モジュール内で定義されたメソッドAny
が引数として受け入れるかどうかを確認することです。これは、前のステートメントと似ていますが、同等ではありません。
julia> z1(x::Any) = 1
z1 (generic function with 1 method)
julia> z2(x) = 1
z2 (generic function with 1 method)
julia> methods(z1)
# 1 method for generic function "z1":
[1] z1(x) in Main at REPL[1]:1
julia> methods(z2)
# 1 method for generic function "z2":
[1] z2(x) in Main at REPL[2]:1
methods
両方の関数のシグネチャがx
として受け入れるので、関数は同じに見えますAny
。
ここで、モジュール/パッケージ内のメソッドが、Any
その中で定義されているメソッドの引数として受け入れるかどうかを確認するには、次のコードのようなものを使用できます(書き留めたばかりなので、あまりテストしていませんが、ほとんどの場合可能なケースをカバー):
function check_declared(m::Module, f::Function)
for mf in methods(f).ms
if mf.module == m
if mf.sig isa UnionAll
b = mf.sig.body
else
b = mf.sig
end
x = getfield(b, 3)
for i in 2:length(x)
if x[i] == Any
println(mf)
break
end
end
end
end
end
function check_declared(m::Module)
for n in names(m)
try
f = m.eval(n)
if f isa Function
check_declared(m, f)
end
catch
# modules sometimes return names that cannot be evaluated in their scope
end
end
end
Base.Iterators
モジュールで実行すると、次のようになります。
julia> check_declared(Iterators)
cycle(xs) in Base.Iterators at iterators.jl:672
drop(xs, n::Integer) in Base.Iterators at iterators.jl:628
enumerate(iter) in Base.Iterators at iterators.jl:133
flatten(itr) in Base.Iterators at iterators.jl:869
repeated(x) in Base.Iterators at iterators.jl:694
repeated(x, n::Integer) in Base.Iterators at iterators.jl:714
rest(itr::Base.Iterators.Rest, state) in Base.Iterators at iterators.jl:465
rest(itr) in Base.Iterators at iterators.jl:466
rest(itr, state) in Base.Iterators at iterators.jl:464
take(xs, n::Integer) in Base.Iterators at iterators.jl:572
そして、たとえばDataStructures.jlパッケージをチェックすると、次のようになります。
julia> check_declared(DataStructures)
compare(c::DataStructures.LessThan, x, y) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps.jl:66
compare(c::DataStructures.GreaterThan, x, y) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps.jl:67
cons(h, t::LinkedList{T}) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\list.jl:13
dec!(ct::Accumulator, x, a::Number) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:86
dequeue!(pq::PriorityQueue, key) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\priorityqueue.jl:288
dequeue_pair!(pq::PriorityQueue, key) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\priorityqueue.jl:328
enqueue!(s::Queue, x) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\queue.jl:28
findkey(t::DataStructures.BalancedTree23, k) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\balanced_tree.jl:277
findkey(m::SortedDict, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_dict.jl:245
findkey(m::SortedSet, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_set.jl:91
heappush!(xs::AbstractArray, x) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\arrays_as_heaps.jl:71
heappush!(xs::AbstractArray, x, o::Base.Order.Ordering) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\arrays_as_heaps.jl:71
inc!(ct::Accumulator, x, a::Number) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:68
incdec!(ft::FenwickTree{T}, left::Integer, right::Integer, val) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\fenwick.jl:64
nil(T) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\list.jl:15
nlargest(acc::Accumulator, n) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:161
nsmallest(acc::Accumulator, n) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:175
reset!(ct::Accumulator{#s14,V} where #s14, x) where V in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:131
searchequalrange(m::SortedMultiDict, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_multi_dict.jl:226
searchsortedafter(m::Union{SortedDict, SortedMultiDict, SortedSet}, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\tokens2.jl:154
sizehint!(d::RobinDict, newsz) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\robin_dict.jl:231
update!(h::MutableBinaryHeap{T,Comp} where Comp, i::Int64, v) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\mutable_binary_heap.jl:250
私が提案するものはあなたの質問に対する完全な解決策ではありませんが、私はそれが私にとって有用であると思ったので、それを共有することを考えました。
編集
上記のコードはf
、Function
唯一であることを受け入れます。一般に、呼び出し可能なタイプを使用できます。次に、check_declared(m::Module, f::Function)
シグネチャをcheck_declared(m::Module, f)
(実際には、関数自体がAny
2番目の引数として許可する:) に変更し、評価されたすべての名前をこの関数に渡すことができます。次に、関数内にmethods(f)
が正かどうかを確認する必要がlength
あります(methods
呼び出し不可の場合は、長さを持つ値が返されます0
)。
hasmethod(f, (Any,) )
戻りfalse
ます。ただし、引数の数を一致させる必要があります(つまりhasmethod(f, (Any,Any) )
、2つの引数を持つ関数の場合)。