pzol / deterministic

Functional - deterministic - Ruby made fun
MIT License
187 stars 18 forks source link

skip step in_sequence #39

Open sphynx79 opened 6 years ago

sphynx79 commented 6 years ago

Hi. I have a question about in_sequence!.

require 'deterministic'

class Foo
  include Deterministic::Prelude

  def call(id: nil)
    result = in_sequence do
      get(:id)        { get_id(id) }
      get(:ctx)       { id == 10 ? Success(id+1) : Failure(1) } }
      get(:ctx)       { Success(id+2) }
      and_yield       { format_response(ctx) }
    end
  end

  def get_id(id)
    id = 10
    Success(id)
  end

  def format_response(id)
    Success("Your id is #{id}")
  end

end

Foo.new.call(id: 10)

My question is how i can skip one step in sequence, in this simple example i want skip the step:

get(:ctx)       { Success(id+2) }

and return me 11, there is one way to integrate Pattern matching and where with in_sequence

Thanks, and congratulation for your gem.

deiwin commented 6 years ago

I'm not exactly sure what you're asking, but I'll assume that you want to know how to skip only a single step instead of skipping all the following steps as Failure does. If that's you're question, then I'd suggest doing something like:

require 'deterministic'

class Foo
  include Deterministic::Prelude

  def call(id: nil)
    result = in_sequence do
      get(:id)  { get_id(id) }
      get(:ctx) { get_ctx(id) }
      and_yield { format_response(ctx) }
    end
  end

  def get_id(id)
    Success(id)
  end

  def get_ctx(id)
    if id == 10
      in_sequence do
        get(:ctx) { Success(id + 1) }
        and_yield { Success(ctx + 2) } # or id + 2 as you have it
      end
    else
      Success(1)
    end
  end

  def format_response(id)
    Success("Your id is #{id}")
  end

end

Foo.new.call(id: 10)

That is, you can't use Failure, because that will abort the entire chain. You can use standard Ruby if/else, however, and nest Result chains within each other.