Advanced Ruby Topics: Concurrency, Reflection, DSLs, and More — Ruby Deep Dive [09]

Bhavyansh @ DiversePixel
3 min readJul 26, 2024

--

We are exploring some advanced Ruby concepts in this article.

1. Concurrency, Parallelism, and the GIL

Concurrency and parallelism are crucial concepts in software development, especially in languages like Ruby. Concurrency refers to the ability of a program to handle multiple tasks simultaneously, while parallelism involves executing multiple tasks simultaneously across multiple processors or cores. Ruby uses a Global Interpreter Lock (GIL) to ensure thread safety by allowing only one thread to execute Ruby code at a time, which can impact performance for CPU-bound tasks despite Ruby’s support for threads.

require 'benchmark'
def cpu_bound_task
10_000_000.times { Math.sqrt(rand) }
end
Benchmark.bm do |x|
x.report("Serial:") do
2.times { cpu_bound_task }
end
x.report("Threaded:") do
2.times.map { Thread.new { cpu_bound_task } }.each(&:join)
end
end

2. Reflection and Introspection

Reflection and introspection in Ruby refer to the ability of a program to examine and modify its structure and behavior at runtime. Ruby provides powerful reflection capabilities through methods like method_missing, send, and define_method, enabling dynamic method invocation, attribute inspection, and more.

class Example
def method_missing(method_name, *args)
if method_name.to_s.start_with?('find_by_')
attribute = method_name.to_s.sub('find_by_', '')
find_by(attribute.to_sym => args.first)
else
super
end
end
def find_by(conditions)
# Simulated database query
"Found by #{conditions.keys.first}: #{conditions.values.first}"
end
end
example = Example.new
puts example.find_by_name("John") # Output: Found by name: John

3. Domain Specific Languages (DSLs)

Domain Specific Languages (DSLs) in Ruby allow developers to create custom syntax and structures tailored to specific domains or tasks. They enhance code expressiveness and readability by providing domain-specific abstractions that resemble natural language or specific problem domains.

class HTMLBuilder
def initialize(&block)
@html = ""
instance_eval(&block)
end
def method_missing(tag, content = nil, &block)
@html << "<#{tag}>"
@html << content if content
instance_eval(&block) if block_given?
@html << "</#{tag}>"
end
def to_s
@html
end
end
html = HTMLBuilder.new do
html do
head { title "My Page" }
body do
h1 "Welcome"
p "This is a custom HTML DSL"
end
end
end
puts html.to_s

4. Ruby’s C Extensions

Ruby allows developers to extend its functionality with C extensions, which can be used to optimize performance-critical parts of applications or integrate with existing C libraries. C extensions in Ruby are typically packaged as Ruby gems and provide seamless integration with Ruby code.

// fast_math.c
#include <ruby.h>
#include <math.h>
static VALUE fast_sqrt(VALUE self, VALUE num) {
return DBL2NUM(sqrt(NUM2DBL(num)));
}
void Init_fast_math() {
VALUE FastMath = rb_define_module("FastMath");
rb_define_singleton_method(FastMath, "sqrt", fast_sqrt, 1);
}
require 'fast_math'
puts FastMath.sqrt(100) # Output: 10.0

5. Debugging and Profiling

Debugging and profiling are essential for optimizing Ruby applications. Ruby provides tools like Benchmark for performance testing and MemoryProfiler for memory usage analysis. These tools help developers identify bottlenecks, optimize code, and ensure efficient resource management.

require 'benchmark'
require 'memory_profiler'
def memory_intensive_task
array = []
10_000.times { array << "a" * 100 }
array
end
report = MemoryProfiler.report do
memory_intensive_task
end
report.pretty_print

6. Ruby’s Memory Management and Garbage Collection

Ruby’s memory management and garbage collection (GC) ensure efficient memory allocation and deallocation. GC in Ruby automatically frees memory occupied by objects that are no longer referenced, preventing memory leaks and optimizing memory usage.

GC.stat

Conclusion

These snippets and explanations cover advanced Ruby topics including concurrency with the GIL, reflection, DSLs, C extensions, debugging, profiling, and memory management. Each topic enhances Ruby developers’ ability to build efficient, scalable, and maintainable applications. These concepts are crucial for mastering Ruby’s capabilities and optimizing performance in real-world scenarios.

--

--

Bhavyansh @ DiversePixel
Bhavyansh @ DiversePixel

Written by Bhavyansh @ DiversePixel

Hey I write about Tech. Join me as I share my tech learnings and insights. 🚀

No responses yet