Avoiding closuring a Proc that's an instance variable

I think at this point some example code would be helpful :sweat_smile:. Something like this?

record Bar, token : String

class BarFactory
  setter token_generator

  def initialize(&@token_generator : -> String); end

  def get_bar
    Bar.new @token_generator.call
  end
end

class Client
  @some_proc : Proc(Bar)

  def initialize(@bar_factory : BarFactory)
    # Some proc just to create a closure
    @some_proc = Proc(Bar).new do
      @bar_factory.get_bar
    end
  end

  def request : String
    @some_proc.call.token
  end

  def with_token(&token_generator : -> String) : self
    instance = self.dup
    instance.token_generator = token_generator
    instance
  end

  protected def token_generator=(token_generator : Proc(String)) : Nil
    @bar_factory.token_generator = token_generator
  end
end

bar_factory = BarFactory.new { "TOKEN_A" }

client = Client.new bar_factory

pp client.request # => "TOKEN_A"

new_token_client = client.with_token { "TOKEN_B" }

pp new_token_client.request # => "TOKEN_B"
pp client.request           # => "TOKEN_B"

Or are you expecting that client keeps using TOKEN_A while only new_token_client uses TOKEN_B?

That would be Redesign HTTP::Client to implement missing features · Issue #6011 · crystal-lang/crystal · GitHub yea.

1 Like