'how to debug an exception with return value nil in ruby class/module error

I create an wrapper class , rclient to make a http call using Excon. in my controller class, I instantiate and call a method on that class. while debugging, I noticed in the post method of the client class @client variable is always nil.

I change the code (see approach 2 ) , instantiate a @cient variable with new instance of Excon and use that variable in the same method , then it is not null. I'm not sure why in approach first, i can access @client variable that is set in the initialize method. any ideas?

approach 1

module API
   class rclient

      def initialize
        @client ||= Excon.new('http://example.com')
      end

      def post
         #error @client is nil 
         post_response = @client.Post(path:'/create', body:{date:'somedata'}); 
      end
   end
end


class my controller < ApplicationController

    def create
       req = API::rclient.new()
       req.post
    end
end

approach 2

module API
   class rclient
      def post
         @client = Excon.new('http://example.com')
         post_response = @client.Post(path:'/create', body:{date:'somedata'}); 
      end
   end
end


class my controller < ApplicationController

    def create
       req = API::rclient.new()
       req.post
    end
end


Solution 1:[1]

@client variable going to be initialized for both variants. Probably smth is missing in this code "adaptation" for the described scenario. Here is slightly adjusted demo code that you can check:

# app.rb
require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)

module API
  class Rclient

    def initialize
      @client ||= Excon.new('http://example.com')
    end

    def post
      post_response = @client.post(path:'/create', body: URI.encode_www_form(date: 'somedata'))
    end
  end

  class Rclient2
    def post
      @client = Excon.new('http://example.com')
      post_response = @client.post(path:'/create', body: URI.encode_www_form(date: 'somedata'))
    end
  end
end

req1 = API::Rclient.new
req2 = API::Rclient2.new

req1.post
req2.post

raise 'First implementation failed' unless req1.instance_variable_get(:@client).is_a?(Excon::Connection)
raise 'Second implementation failed' unless req2.instance_variable_get(:@client).is_a?(Excon::Connection)
# Gemfile
source 'https://rubygems.org' 
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.5'

gem 'excon'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yurii