Skip to content

generator

Ruby only
Bmg.generate(1, 10)
Bmg.generate(1, 100, step: 10)
Bmg.generate(from, to, as: :n, step: 2)

Generate a sequence of values as a relation.

Example: I need a relation of consecutive integers to join with other data or generate test data.

The generator creates a relation from a sequence of values, similar to PostgreSQL’s generate_series. It produces tuples with a single attribute containing values from a starting point to an ending point.

This is a factory method called on Bmg directly, not an operator called on an existing relation.

Parameters:

  • from - Starting value (required)
  • to - Ending value (required)
  • options:
    • as - Attribute name for the generated value (default: :i)
    • step - Increment between values (default: 1), can be:
      • A number (positive or negative)
      • A lambda for custom stepping
  • from and to must be provided
  • Values must support comparison (>, <) and addition (+) operations
Bmg.generate(1, 5).to_a
=>
[{:i=>1}, {:i=>2}, {:i=>3}, {:i=>4}, {:i=>5}]
Bmg.generate(1, 3, as: :number).to_a
=>
[{:number=>1}, {:number=>2}, {:number=>3}]
Bmg.generate(0, 10, step: 2).to_a
=>
[{:i=>0}, {:i=>2}, {:i=>4}, {:i=>6}, {:i=>8}, {:i=>10}]

Use a negative step to count down:

Bmg.generate(5, 1, step: -1).to_a
=>
[{:i=>5}, {:i=>4}, {:i=>3}, {:i=>2}, {:i=>1}]

Generate consecutive dates:

require 'date'
Bmg.generate(Date.new(2024, 1, 1), Date.new(2024, 1, 5)).to_a
=>
[{:i=>Date.new(2024, 1, 1)},
{:i=>Date.new(2024, 1, 2)},
{:i=>Date.new(2024, 1, 3)},
{:i=>Date.new(2024, 1, 4)},
{:i=>Date.new(2024, 1, 5)}]

Use a lambda for non-linear sequences:

# Exponential: 1, 2, 4, 8
Bmg.generate(1, 10, step: ->(i) { i * 2 }).to_a
=>
[{:i=>1}, {:i=>2}, {:i=>4}, {:i=>8}]
# Generate IDs and extend with computed values
Bmg.generate(1, 100, as: :id)
.extend(
name: ->(t) { "User #{t[:id]}" },
email: ->(t) { "user#{t[:id]}@example.com" }
)
.to_a
=>
[{:id=>1, :name=>"User 1", :email=>"user1@example.com"},
{:id=>2, :name=>"User 2", :email=>"user2@example.com"},
...]

Unlike most Bmg operations which are lazy, generator creates tuples on-demand during iteration. Be cautious with very large ranges as they will be fully materialized when converted to an array or iterated.