From 4406f8e258500d4b01e294d7a348d3e8a96e5276 Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Sat, 14 Oct 2017 23:00:40 +0200 Subject: [PATCH] Call Object#method if method accessor is called with arguments --- lib/stripe/stripe_object.rb | 11 ++++++++++- test/stripe/stripe_object_test.rb | 12 ++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/stripe/stripe_object.rb b/lib/stripe/stripe_object.rb index d4795c2b..1e6c4701 100644 --- a/lib/stripe/stripe_object.rb +++ b/lib/stripe/stripe_object.rb @@ -241,7 +241,16 @@ module Stripe next if protected_fields.include?(k) next if @@permanent_attributes.include?(k) - define_method(k) { @values[k] } + if k == :method + # Object#method is a built-in Ruby method that accepts a symbol + # and returns the corresponding Method object. Because the API may + # also use `method` as a field name, we check the arity of *args + # to decide whether to act as a getter or call the parent method. + define_method(k) { |*args| args.empty? ? @values[k] : super(*args) } + else + define_method(k) { @values[k] } + end + define_method(:"#{k}=") do |v| if v == "" raise ArgumentError, "You cannot set #{k} to an empty string. " \ diff --git a/test/stripe/stripe_object_test.rb b/test/stripe/stripe_object_test.rb index 60bd02be..dec53803 100644 --- a/test/stripe/stripe_object_test.rb +++ b/test/stripe/stripe_object_test.rb @@ -423,5 +423,17 @@ module Stripe expected_hash = { api_key: "apikey" } assert_equal expected_hash, m.instance_variable_get("@opts") end + + context "#method" do + should "act as a getter is not argument is provided" do + obj = Stripe::StripeObject.construct_from(id: 1, method: "foo") + assert_equal "foo", obj.method + end + + should "call Object#method if an argument is provided" do + obj = Stripe::StripeObject.construct_from(id: 1, method: "foo") + assert obj.method(:id).is_a?(Method) + end + end end end