microsoft_graph のコードを読む - 虚無庵 microsoft_graph のコードを読む(2) - 虚無庵
前回は OData::Service#initialize について読みました。
今回は再度 MicrosoftGraph#initialize に戻ります。
class MicrosoftGraph
attr_reader :service
BASE_URL = "https://graph.microsoft.com/v1.0/"
def initialize(options = {}, &auth_callback)
@service = OData::Service.new(
api_version: options[:api_version],
auth_callback: auth_callback,
base_url: BASE_URL,
metadata_file: options[:cached_metadata_file]
)
@association_collections = {}
unless MicrosoftGraph::ClassBuilder.loaded?
MicrosoftGraph::ClassBuilder.load!(service)
end
end
def containing_navigation_property(type_name)
navigation_properties.values.find do |navigation_property|
navigation_property.collection? && navigation_property.type.name == "Collection(#{type_name})"
end
end
def path; end
end
MicrosoftGraph::ClassBuilder
ひとまず @association_collections は置いておいて、MicrosoftGraph::ClassBuilder を読む
MicrosoftGraph::ClassBuilder.loaded?
def self.loaded? @@loaded end
クラス変数 @@loaded を返すのみです。@@loaded はデフォルトで false が代入されています。
MicrosoftGraph::ClassBuilder.load!(service)
def self.load!(service)
if !@@loaded
@service_namespace = service.namespace
service.entity_types.each do |entity_type|
create_class! entity_type
end
service.complex_types.each do |complex_type|
create_class! complex_type
end
service.entity_sets.each do |entity_set|
add_graph_association! entity_set
end
service.actions.each do |action|
add_action_method! action
end
service.functions.each do |function|
add_function_method! function
end
service.singletons.each do |singleton|
class_name = classify(singleton.type_name)
MicrosoftGraph.instance_eval do
resource_name = singleton.name
define_method(OData.convert_to_snake_case(resource_name)) do
MicrosoftGraph
.const_get(class_name)
.new(
graph: self,
resource_name: resource_name,
parent: self
).tap(&:fetch)
end
end
end
MicrosoftGraph.instance_eval do
define_method(:navigation_properties) do
service.entity_sets
.concat(service.singletons)
.map { |navigation_property|
[navigation_property.name.to_sym, navigation_property]
}.to_h
end
end
@@loaded = true
end
end
はい、もう勘の良い方はお気づきですね。コードジェネレーターを使わずに機能を実現できているのは、Ruby のメタプログラミング技法を使っているからです。
これを読むのが本当にねぇ…。という訳で、限られた昼休みではなくちゃんと時間を取って書きます。
(続く?)