DEV Community

subhashree
subhashree

Posted on

Ruby Lambda when and how ??????

Most of us would have seen 'n' number of posts on how to use lambda( I have seen at least 10+ posts), but eventually will end up writing common methods. I have never used block call or yield, as it looks like a complicated feature that my brain never wants to learn it( "why to complicate things ! :D").

Unfortunately, I have to use it in my work, to avoid duplicate issues. Then I told myself, if not now then when?

Before jumping into the code, we should be aware of what is lambda and its syntax.

Alt Text


Source: https://www.rubyguides.com/2016/02/ruby-procs-and-lambdas/

Note: '->' is equivalent to lambda literal

class WithoutLambdaExample
def self.run_examples
scores = [1, 2, 3, 4]
ClassA.calculate_score(scores)
scores = [4, 5, 6, 7]
ClassB.calculate_score(scores)
scores = [8, 9, 10, 11]
ClassC.calculate_score(scores)
scores = [12, 13, 15, 14]
ClassD.calculate_score(scores)
end
end
class ClassA
THRESHOLD = 5
FACTOR = 2
def self.calculate_score(scores)
score_point = process_score(scores)
puts "Class A: score point #{score_point}"
end
def self.process_score(scores)
sum = 0
unless scores.empty?
scores.each do |score|
sum += score if Utils.allowed_score(score) && (score * FACTOR > THRESHOLD)
end
end
sum
end
end
class ClassB
THRESHOLD = 10
FACTOR = 2.5
def self.calculate_score(scores)
score_point = process_score(scores)
puts "Class B: score point #{score_point}"
end
def self.process_score(scores)
sum = 0
unless scores.empty?
scores.each do |score|
sum += score if Utils.allowed_score(score) && (score + FACTOR < THRESHOLD)
end
end
sum
end
end
class ClassC
THRESHOLD = 5
FACTOR = 3
def self.calculate_score(scores)
score_point = process_score(scores)
puts "Class C: score point #{score_point}"
end
def self.process_score(scores)
sum = 0
unless scores.empty?
scores.each do |score|
sum += score if Utils.allowed_score(score) && (score - FACTOR >= THRESHOLD)
end
end
sum
end
end
class ClassD
THRESHOLD = 8
FACTOR = 3.5
def self.calculate_score(scores)
score_point = process_score(scores)
puts "Class D: score point #{score_point}"
end
def self.process_score(scores)
sum = 0
unless scores.empty?
scores.each do |score|
sum += score if Utils.allowed_score(score) && (score / FACTOR < THRESHOLD)
end
end
sum
end
end
class Utils
LOW_RANGE = 2
HIGH_RANGE = 15
def self.allowed_score(score)
score >= LOW_RANGE && score <= HIGH_RANGE
end
end

Now you have seen that condition alone changes but calculating steps remain the same.

How these repeating steps can be moved to a common method?

We can pass FACTOR and THRESHOLD, but how about operators?

Is there a way that I can pass this condition alone from the calling method and make it simple?

To answer all the above questions, we have our LAMBDA for it.

class LambdaExample
def self.run_examples
scores = [1, 2, 3, 4]
ClassA.calculate_score(scores)
scores = [4, 5, 6, 7]
ClassB.calculate_score(scores)
scores = [8, 9, 10, 11]
ClassC.calculate_score(scores)
scores = [12, 13, 15, 14]
ClassD.calculate_score(scores)
end
end
class ClassA
THRESHOLD = 5
FACTOR = 2
def self.calculate_score(scores)
condition_block = lambda { |score| (score * FACTOR) > THRESHOLD }
score_point = Processor.process_score(scores, &condition_block)
puts "Class A: score point #{score_point}"
end
end
class ClassB
THRESHOLD = 10
FACTOR = 2.5
def self.calculate_score(scores)
condition_block = lambda { |score| (score + FACTOR) < THRESHOLD }
score_point = Processor.process_score(scores, &condition_block)
puts "Class B: score point #{score_point}"
end
end
class ClassC
THRESHOLD = 5
FACTOR = 3
def self.calculate_score(scores)
condition_block = lambda { |score| (score - FACTOR) >= THRESHOLD }
score_point = Processor.process_score(scores, &condition_block)
puts "Class C: score point #{score_point}"
end
end
class ClassD
THRESHOLD = 8
FACTOR = 3.5
def self.calculate_score(scores)
condition_block = lambda { |score| (score / FACTOR) < THRESHOLD }
score_point = Processor.process_score(scores, &condition_block)
puts "Class D: score point #{score_point}"
end
end
class Processor
LOW_RANGE = 2
HIGH_RANGE = 15
def self.process_score(scores, &condition_block)
sum = 0
unless scores.empty?
scores.each do |score|
sum += score if allowed_score(score) && !condition_block.nil? && condition_block.call(score)
end
end
sum
end
def self.allowed_score(score)
score >= LOW_RANGE && score <= HIGH_RANGE
end
end
view raw lambda.rb hosted with ❤ by GitHub

Now repeating steps are moved into a common method called process_score, having score and lambda as arguments.

We can do this in different ways, but this post is exclusively for how we can make use of lambda.

Thanks for reading! Suggestions are welcome!
Note: This is post originally posted in my medium account https://medium.com/@subha220993/oh-my-lambda-a1386a0bdad2

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →