Railway-Oriented Programming (ROP) áp dụng Result pattern — mỗi bước trả về success hoặc failure, chain chỉ tiếp tục khi success.
Cách đơn giản nhất trong Ruby là dùng gem dry-monads hoặc tự implement với Struct:
Success = Struct.new(:value)
Failure = Struct.new(:error)
def parse_age(input)
n = Integer(input)
n > 0 ? Success.new(n) : Failure.new("Age must be positive")
rescue ArgumentError
Failure.new("Not a valid integer")
end
def validate_adult(age)
age >= 18 ? Success.new(age) : Failure.new("Must be 18+")
end
result = parse_age("25")
result = validate_adult(result.value) if result.is_a?(Success)
case result
in Success[value] then puts "Valid age: #{value}"
in Failure[error] then puts "Error: #{error}"
endGem dry-rb (dry-monads, dry-validation) cung cấp full ROP/monad cho production.
Pattern này tránh exception cho business logic — exception chỉ dùng cho lỗi hệ thống thực sự.
Railway-Oriented Programming (ROP) applies the Result pattern — each step returns success or failure, and the chain only continues on success.
The simplest Ruby approach uses a Struct:
Success = Struct.new(:value)
Failure = Struct.new(:error)
def parse_age(input)
n = Integer(input)
n > 0 ? Success.new(n) : Failure.new("Age must be positive")
rescue ArgumentError
Failure.new("Not a valid integer")
end
def validate_adult(age)
age >= 18 ? Success.new(age) : Failure.new("Must be 18+")
end
result = parse_age("25")
result = validate_adult(result.value) if result.is_a?(Success)
case result
in Success[value] then puts "Valid age: #{value}"
in Failure[error] then puts "Error: #{error}"
endThe dry-rb family (dry-monads, dry-validation) provides full ROP/monad support for production.
The pattern avoids exceptions for business logic — exceptions are reserved for true system errors.