Ruby
Overview
Ruby is a dynamic, object-oriented programming language focused on simplicity and productivity. Runner Codes provides Ruby for executing Ruby scripts.
Specifications
| Property | Value |
|---|---|
| Docker Image | ruby:3.3-alpine |
| Version | Ruby 3.3.10 |
| Rootfs Size | 200 MB |
| Execution | Interpreted |
| File Extension | .rb |
| Run Command | ruby {file} |
| Execution Time | ~83ms |
1. Create Rootfs from Docker
sudo infra.operator rootfs from-docker --name ruby --image ruby:3.3-alpine --size 200
2. Create Snapshot
sudo infra.operator snapshot create --lang ruby --mem 512 --vcpus 1
3. Upload rootfs to S3
sudo infra.operator rootfs upload --lang ruby --bucket runner-codes
3. Upload snapshot to S3
sudo infra.operator snapshot upload --lang ruby --bucket runner-codes
4. Test Execution
sudo infra.operator host --lang ruby --code 'puts "Hello from Ruby #{RUBY_VERSION}"' --mem 512 --vcpus 1 --snapshot
Execution Flow
Examples
Hello World
Request
{
"trace_id": "ruby-hello-001",
"lang": "ruby",
"code": "puts 'Hello from Ruby!'",
"timeout": 10
}
Response
{
"trace_id": "ruby-hello-001",
"stdout": "Hello from Ruby!\n",
"stderr": "",
"exit_code": 0
}
Arrays and Blocks
Request
{
"trace_id": "ruby-array-001",
"lang": "ruby",
"code": "numbers = [1, 2, 3, 4, 5]\nsquares = numbers.map { |n| n ** 2 }\nputs \"Numbers: #{numbers}\"\nputs \"Squares: #{squares}\"\nputs \"Sum: #{squares.sum}\"",
"timeout": 10
}
Response
{
"trace_id": "ruby-array-001",
"stdout": "Numbers: [1, 2, 3, 4, 5]\nSquares: [1, 4, 9, 16, 25]\nSum: 55\n",
"stderr": "",
"exit_code": 0
}
Classes
Request
{
"trace_id": "ruby-class-001",
"lang": "ruby",
"code": "class Calculator\n def initialize\n @result = 0\n end\n \n def add(x)\n @result += x\n self\n end\n \n def multiply(x)\n @result *= x\n self\n end\n \n def result\n @result\n end\nend\n\ncalc = Calculator.new\nresult = calc.add(5).multiply(3).add(10).result\nputs \"Result: #{result}\"",
"timeout": 10
}
Response
{
"trace_id": "ruby-class-001",
"stdout": "Result: 25\n",
"stderr": "",
"exit_code": 0
}
Hashes
Request
{
"trace_id": "ruby-hash-001",
"lang": "ruby",
"code": "user = {\n name: 'Alice',\n age: 30,\n city: 'NYC'\n}\n\nuser.each do |key, value|\n puts \"#{key}: #{value}\"\nend",
"timeout": 10
}
Response
{
"trace_id": "ruby-hash-001",
"stdout": "name: Alice\nage: 30\ncity: NYC\n",
"stderr": "",
"exit_code": 0
}
Blocks and Procs
Request
{
"trace_id": "ruby-block-001",
"lang": "ruby",
"code": "def with_timing\n start = Time.now\n yield\n elapsed = Time.now - start\n puts \"Elapsed: #{elapsed.round(4)}s\"\nend\n\nwith_timing do\n sum = (1..1000).reduce(:+)\n puts \"Sum: #{sum}\"\nend",
"timeout": 10
}
Response
{
"trace_id": "ruby-block-001",
"stdout": "Sum: 500500\nElapsed: 0.0001s\n",
"stderr": "",
"exit_code": 0
}
JSON Processing
Request
{
"trace_id": "ruby-json-001",
"lang": "ruby",
"code": "require 'json'\n\ndata = { name: 'Alice', scores: [85, 90, 92] }\njson = JSON.pretty_generate(data)\nputs json\n\nparsed = JSON.parse(json)\nputs \"Name: #{parsed['name']}\"\nputs \"Average: #{parsed['scores'].sum / parsed['scores'].size}\"",
"timeout": 10
}
Response
{
"trace_id": "ruby-json-001",
"stdout": "{\n \"name\": \"Alice\",\n \"scores\": [\n 85,\n 90,\n 92\n ]\n}\nName: Alice\nAverage: 89\n",
"stderr": "",
"exit_code": 0
}
Complex Test: Comprehensive Ruby
Request
{
"trace_id": "ruby-complex-001",
"lang": "ruby",
"code": "puts '=== Ruby Complex Test ==='\nputs\n\n# Test 1: Fibonacci with memoization\nputs '1. Fibonacci with memoization:'\n@memo = {}\ndef fib(n)\n return @memo[n] if @memo.key?(n)\n return n if n <= 1\n @memo[n] = fib(n - 1) + fib(n - 2)\nend\nfibs = (0..14).map { |i| fib(i) }\nputs \" First 15: #{fibs}\"\nputs \" Fib(50) = #{fib(50)}\"\n\n# Test 2: QuickSort\nputs\nputs '2. QuickSort:'\ndef quicksort(arr)\n return arr if arr.length <= 1\n pivot = arr[arr.length / 2]\n left = arr.select { |x| x < pivot }\n middle = arr.select { |x| x == pivot }\n right = arr.select { |x| x > pivot }\n quicksort(left) + middle + quicksort(right)\nend\nunsorted = [64, 34, 25, 12, 22, 11, 90]\nputs \" Input: #{unsorted}\"\nputs \" Output: #{quicksort(unsorted)}\"\n\n# Test 3: Classes and modules\nputs\nputs '3. Classes and modules:'\nmodule Speakable\n def speak\n raise NotImplementedError\n end\nend\n\nclass Animal\n include Speakable\n attr_reader :name\n def initialize(name)\n @name = name\n end\nend\n\nclass Dog < Animal\n def speak\n \"#{name} says Woof!\"\n end\nend\n\nclass Cat < Animal\n def speak\n \"#{name} says Meow!\"\n end\nend\n\nanimals = [Dog.new('Rex'), Cat.new('Whiskers'), Dog.new('Buddy')]\nanimals.each { |a| puts \" #{a.speak}\" }\n\n# Test 4: Enumerable methods\nputs\nputs '4. Enumerable methods:'\nnumbers = (1..10).to_a\nsquares = numbers.map { |x| x ** 2 }\nevens = numbers.select(&:even?)\nsum = squares.reduce(:+)\nputs \" Numbers: #{numbers}\"\nputs \" Squares: #{squares}\"\nputs \" Evens: #{evens}\"\nputs \" Sum of squares: #{sum}\"\n\n# Test 5: Hashes and symbols\nputs\nputs '5. Hashes and symbols:'\npeople = [\n { name: 'Alice', age: 30, city: 'NYC' },\n { name: 'Bob', age: 25, city: 'LA' },\n { name: 'Charlie', age: 35, city: 'Chicago' }\n]\nby_city = people.map { |p| [p[:city], p[:name]] }.to_h\npeople.each { |p| puts \" #{p[:name]} (#{p[:age]}) from #{p[:city]}\" }\nputs \" By city: #{by_city}\"\n\n# Test 6: Procs and lambdas\nputs\nputs '6. Procs and lambdas:'\nmultiplier = ->(factor) { ->(x) { x * factor } }\ndouble = multiplier.call(2)\ntriple = multiplier.call(3)\nputs \" double(5) = #{double.call(5)}\"\nputs \" triple(5) = #{triple.call(5)}\"\n\n# Test 7: Blocks and yield\nputs\nputs '7. Blocks and yield:'\ndef with_timing\n start = Time.now\n result = yield\n elapsed = Time.now - start\n { result: result, time: elapsed.round(6) }\nend\nresult = with_timing { (1..1000).reduce(:+) }\nputs \" Sum result: #{result[:result]}\"\nputs \" Time: #{result[:time]}s\"\n\n# Test 8: String and regex\nputs\nputs '8. String operations:'\ntext = 'Hello, World! Welcome to Ruby.'\nputs \" Original: #{text}\"\nputs \" Upper: #{text.upcase}\"\nputs \" Words: #{text.split.count}\"\nputs \" Emails in '[email protected] and [email protected]': #{['[email protected] and [email protected]'.scan(/\\S+@\\S+\\.\\w+/)].flatten}\"\n\nputs\nputs '=== All tests passed ==='",
"timeout": 30
}
Response
{
"trace_id": "ruby-complex-001",
"stdout": "=== Ruby Complex Test ===\n\n1. Fibonacci with memoization:\n First 15: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]\n Fib(50) = 12586269025\n\n2. QuickSort:\n Input: [64, 34, 25, 12, 22, 11, 90]\n Output: [11, 12, 22, 25, 34, 64, 90]\n\n3. Classes and modules:\n Rex says Woof!\n Whiskers says Meow!\n Buddy says Woof!\n\n4. Enumerable methods:\n Numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n Squares: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n Evens: [2, 4, 6, 8, 10]\n Sum of squares: 385\n\n5. Hashes and symbols:\n Alice (30) from NYC\n Bob (25) from LA\n Charlie (35) from Chicago\n By city: {\"NYC\"=>\"Alice\", \"LA\"=>\"Bob\", \"Chicago\"=>\"Charlie\"}\n\n6. Procs and lambdas:\n double(5) = 10\n triple(5) = 15\n\n7. Blocks and yield:\n Sum result: 500500\n Time: 0.000123s\n\n8. String operations:\n Original: Hello, World! Welcome to Ruby.\n Upper: HELLO, WORLD! WELCOME TO RUBY.\n Words: 5\n Emails in '[email protected] and [email protected]': [\"[email protected]\", \"[email protected]\"]\n\n=== All tests passed ===\n",
"stderr": "",
"exit_code": 0
}
Performance
| Operation | Time |
|---|---|
| Hello World | ~50ms |
| Array operations | ~10ms |
| JSON parse/generate | ~5ms |
| Class instantiation | ~1ms |
Limitations
warning
The Ruby environment has the following limitations:
- No gems: Only standard library
- No network: Net::HTTP operations will fail
- Memory limit: 512 MiB
- Timeout: Configurable, default 10 seconds
- No file persistence: Files lost after execution
Best Practices
Best Practices
- Use puts for output — Use puts for output to stdout. Use p for debugging.
- Use blocks effectively — Ruby's block syntax is powerful for iterators and callbacks.
- Use standard library — Only Ruby standard library is available, no gems.
- Handle exceptions — Use begin/rescue/end for error handling.