microsoft_graph のコードを読む(3)
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 のメタプログラミング技法を使っているからです。
これを読むのが本当にねぇ…。という訳で、限られた昼休みではなくちゃんと時間を取って書きます。
(続く?)