Skip to content

Commit bd6dcb2

Browse files
committed
Add sample posts
1 parent 3682550 commit bd6dcb2

File tree

5 files changed

+797
-22
lines changed

5 files changed

+797
-22
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
title: "Ruby Blocks and Iterators: The Heart of Ruby Programming"
3+
date: 2025-09-10 14:30:00 -0800
4+
categories: [Programming, Ruby]
5+
tags: [ruby, blocks, iterators, programming]
6+
author: dain
7+
---
8+
9+
Ruby's blocks and iterators are one of its most powerful and distinctive features. They provide an elegant way to work with collections and implement higher-order functions.
10+
11+
## What are Blocks?
12+
13+
Blocks in Ruby are chunks of code that can be passed to methods. They're like anonymous functions that can be executed within the context of a method.
14+
15+
```ruby
16+
# Block with do...end
17+
[1, 2, 3, 4, 5].each do |number|
18+
puts number * 2
19+
end
20+
21+
# Block with curly braces
22+
[1, 2, 3, 4, 5].each { |number| puts number * 2 }
23+
```
24+
25+
## Common Iterators
26+
27+
### each
28+
The most basic iterator that executes a block for each element:
29+
30+
```ruby
31+
fruits = ['apple', 'banana', 'cherry']
32+
fruits.each { |fruit| puts "I love #{fruit}!" }
33+
```
34+
35+
### map/collect
36+
Transforms each element and returns a new array:
37+
38+
```ruby
39+
numbers = [1, 2, 3, 4, 5]
40+
squared = numbers.map { |n| n ** 2 }
41+
# => [1, 4, 9, 16, 25]
42+
```
43+
44+
### select/filter
45+
Returns elements that match a condition:
46+
47+
```ruby
48+
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
49+
evens = numbers.select { |n| n.even? }
50+
# => [2, 4, 6, 8, 10]
51+
```
52+
53+
### reject
54+
Returns elements that don't match a condition:
55+
56+
```ruby
57+
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
58+
odds = numbers.reject { |n| n.even? }
59+
# => [1, 3, 5, 7, 9]
60+
```
61+
62+
## Creating Custom Iterators
63+
64+
You can create your own methods that accept blocks:
65+
66+
```ruby
67+
def repeat(times)
68+
counter = 0
69+
while counter < times
70+
yield(counter)
71+
counter += 1
72+
end
73+
end
74+
75+
repeat(3) { |i| puts "Iteration #{i}" }
76+
```
77+
78+
## Proc and Lambda
79+
80+
For more advanced use cases, Ruby provides `Proc` and `lambda`:
81+
82+
```ruby
83+
# Proc
84+
my_proc = Proc.new { |x| x * 2 }
85+
puts my_proc.call(5) # => 10
86+
87+
# Lambda
88+
my_lambda = lambda { |x| x * 2 }
89+
puts my_lambda.call(5) # => 10
90+
91+
# Lambda with stabby syntax
92+
my_lambda = ->(x) { x * 2 }
93+
puts my_lambda.call(5) # => 10
94+
```
95+
96+
Blocks and iterators make Ruby code more expressive and functional. They're essential tools for any Ruby developer!
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
---
2+
title: "Ruby Metaprogramming: Writing Code that Writes Code"
3+
date: 2025-09-11 09:15:00 -0800
4+
categories: [Programming, Ruby]
5+
tags: [ruby, metaprogramming, dynamic, reflection]
6+
author: dain
7+
---
8+
9+
Metaprogramming is one of Ruby's most powerful features, allowing you to write code that manipulates code itself at runtime. It's what makes Ruby so flexible and dynamic.
10+
11+
## What is Metaprogramming?
12+
13+
Metaprogramming is the practice of writing programs that can read, generate, analyze, or transform other programs, and even modify themselves while running.
14+
15+
## Dynamic Method Definition
16+
17+
You can define methods dynamically using `define_method`:
18+
19+
```ruby
20+
class Person
21+
%w[name age email].each do |attribute|
22+
define_method attribute do
23+
instance_variable_get("@#{attribute}")
24+
end
25+
26+
define_method "#{attribute}=" do |value|
27+
instance_variable_set("@#{attribute}", value)
28+
end
29+
end
30+
end
31+
32+
person = Person.new
33+
person.name = "John"
34+
person.age = 30
35+
puts person.name # => "John"
36+
```
37+
38+
## Method Missing
39+
40+
The `method_missing` hook allows you to respond to undefined method calls:
41+
42+
```ruby
43+
class MagicHash
44+
def initialize
45+
@data = {}
46+
end
47+
48+
def method_missing(method_name, *args)
49+
if method_name.to_s.end_with?('=')
50+
# Setter method
51+
key = method_name.to_s.chomp('=')
52+
@data[key] = args.first
53+
else
54+
# Getter method
55+
@data[method_name.to_s]
56+
end
57+
end
58+
59+
def respond_to_missing?(method_name, include_private = false)
60+
true
61+
end
62+
end
63+
64+
hash = MagicHash.new
65+
hash.username = "johndoe"
66+
hash.email = "[email protected]"
67+
puts hash.username # => "johndoe"
68+
```
69+
70+
## Class Macros
71+
72+
Ruby's `attr_accessor`, `attr_reader`, and `attr_writer` are examples of class macros:
73+
74+
```ruby
75+
class Product
76+
attr_accessor :name, :price
77+
attr_reader :id
78+
79+
def initialize(id, name, price)
80+
@id = id
81+
@name = name
82+
@price = price
83+
end
84+
end
85+
```
86+
87+
You can create your own class macros:
88+
89+
```ruby
90+
class ActiveRecord
91+
def self.validates_presence_of(*attributes)
92+
attributes.each do |attribute|
93+
define_method "validate_#{attribute}" do
94+
if instance_variable_get("@#{attribute}").nil?
95+
raise "#{attribute} cannot be nil"
96+
end
97+
end
98+
end
99+
end
100+
end
101+
102+
class User < ActiveRecord
103+
validates_presence_of :email, :password
104+
105+
attr_accessor :email, :password
106+
end
107+
```
108+
109+
## Module Inclusion Hooks
110+
111+
Ruby provides hooks that are called when modules are included:
112+
113+
```ruby
114+
module Trackable
115+
def self.included(base)
116+
base.extend(ClassMethods)
117+
base.class_eval do
118+
attr_accessor :created_at, :updated_at
119+
end
120+
end
121+
122+
module ClassMethods
123+
def track_creation
124+
define_method :initialize do |*args|
125+
super(*args)
126+
@created_at = Time.now
127+
@updated_at = Time.now
128+
end
129+
end
130+
end
131+
132+
def touch
133+
@updated_at = Time.now
134+
end
135+
end
136+
137+
class Article
138+
include Trackable
139+
track_creation
140+
141+
attr_accessor :title, :content
142+
end
143+
```
144+
145+
## Eval Family
146+
147+
Ruby provides several `eval` methods for dynamic code execution:
148+
149+
```ruby
150+
# eval - executes a string as Ruby code
151+
code = "puts 'Hello from eval!'"
152+
eval(code)
153+
154+
# instance_eval - executes code in the context of an object
155+
person = Person.new
156+
person.instance_eval do
157+
@name = "Alice"
158+
@age = 25
159+
end
160+
161+
# class_eval - executes code in the context of a class
162+
Person.class_eval do
163+
def greet
164+
"Hello, I'm #{@name}"
165+
end
166+
end
167+
```
168+
169+
## Best Practices
170+
171+
1. **Use metaprogramming sparingly** - It can make code hard to understand and debug
172+
2. **Prefer explicit over implicit** - Clear code is better than clever code
173+
3. **Document your metaprogramming** - Future you will thank you
174+
4. **Test thoroughly** - Dynamic code is harder to catch with static analysis
175+
176+
Metaprogramming is a double-edged sword. Use it wisely to create elegant, DRY code, but don't sacrifice readability for cleverness.

0 commit comments

Comments
 (0)