почему я получаю ноль в ruby ошибка класса / модуля - PullRequest
0 голосов
/ 17 марта 2020

Я создаю класс-обёртку, чтобы сделать http-вызов с использованием Excon. в моем классе контроллера я создаю экземпляр и вызываю метод для этого класса. во время отладки я заметил, что в методе post переменная @client класса клиента всегда равна nil.

Я изменяю код (см. Подход 2), создаю экземпляр переменной @cient с новым экземпляром Excon и использую эту переменную в том же методе, тогда она не равна нулю. Я не уверен, почему в подходе сначала я могу получить доступ к переменной @client, которая установлена ​​в методе initialize. есть идеи?

подход 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

подход 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

1 Ответ

0 голосов
/ 17 марта 2020

@client переменная будет инициализирована для обоих вариантов. Вероятно, что-то не хватает в этом коде «адаптации» для описанного сценария. Вот немного настроенный демонстрационный код, который вы можете проверить:

# 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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...