
Есть люди, уверенные в том, что подобные ивенты — трата времени. Я так не считаю, и вот почему:
Size: a a a
class Foo
def get_users_for_current_time
User.where(created_at: Time.now)
# ...
end
end
describe Foo do
before do
@time = Time.now
Time.stub(:now).and_return(@time)
end
...
end
class Logger
def call(message)
# ...
print_message(message)
end
end
class JSONLogger < Logger
def call(message)
# ...
to_json(message)
end
end
class Foo
def get_users_for_current_time(time: Time.now)
User.where(created_at: time)
# ...
end
end
describe Foo do
let(:time) { Time.now }
it { expect(Foo.get_users_for_current_time(time)).to eq ... }
# ...
end
convert_to_string = :to_s.to_proc # => proc
convert_to_string.call(123) # => "123"
pov2 = -> (x) { x ** 2 } # => proc
pov2.call(5) # => 25
class ToString
def call(object)
String(object)
end
end
to_string = ToString.new
to_string.call(:one) # => 'one'
:to_s.to_proc
. Так, интеракторы, оперейшены и сервисы — это тоже функциональные объекты.
plusOne = (+1)
square = (^2)
squareAndPlusOne = plusOne . square
squareAndPlusOne(4) # => (4 ^ 2) + 1 == 17
convert_to_json = Transproc(:load_json) # создаем первый функциональный объект
symbolize_keys = Transproc(:symbolize_keys) # второй
symbolize_json = convert_to_json >> symbolize_keys # объединяем их в один
symbolize_json.call('[{"name":"Jane"}]')
# => [{ :name => "Jane" }]
result = ValidateUser.new.call( ... )
result = result.success? ? CreateUser.new.call( ... ) : result
if result2.success?
redirect_to
else
render
end
validation_post_result = ValidatePost.new.call( ... )
validation_comments_result = ValidateComments.new.call( ... )
if validation_post_result.success? && validation_comments_result.success?
...
end
UserCreator.call(...) && CommentCreator.call(...) && ...
class UserOperation
def call(payload)
result = ValidateUser.new.call( ... )
result = result.success? ? CreateUser.new.call( ... ) : result
result
end
end
if UserOperation.new.call({ ... }).success?
...
end
success data → first function object → success data
failed data → first function object → failed data
success data → second function object → success data
failed data → second function object → failed data
Wf.new
.chain(user1: :user) { FetchUser.new(1) }
.chain(user2: :user) { FetchUser.new(2) }
.chain {|outflow| puts(outflow.user1, outflow.user2) } # report success
.on_dam {|error| puts(error) } # report error
class CreateUser
include Dry::Transaction
step :validate
step :persist
def validate(input)
# ...
end
def persist(input)
# ...
end
end
CreateUser.new.call(name: "Jane", email: "jane@doe.com") do |m|
m.success do |value|
# ...
end
m.failure do |error|
# ...
end
end