Hello World & Running
Hello, World
Ruby programs need no
#include directives, no main function, and no return 0 — top-level code executes immediately, line by line.#include <stdio.h>
int main(void) {
printf("Hello, World!\n");
return 0;
}puts "Hello, World!"puts prints a value followed by a newline — the direct equivalent of printf("...\n").Running a program
Ruby is interpreted — there is no compile step, no object file, no linker.
// Compile then run:
// gcc -o hello hello.c && ./hello
// With math:
// gcc hello.c -lm -o hello
// Check with:
// ./hello; echo "exit: $?"# Run directly (no compile step):
# ruby hello.rb
#
# Run a one-liner:
# ruby -e 'puts "Hello!"'
#
# Interactive REPL:
# irbruby hello.rb parses, compiles to bytecode, and executes in one command. For quick experiments, irb (Interactive Ruby) provides a REPL. The -e flag executes a one-liner without creating a file.Comments
Ruby uses
# for single-line comments; the =begin/=end block form exists but is almost never used in practice.#include <stdio.h>
// Single-line comment
/* Multi-line
comment */
int main(void) {
int count = 0; /* inline comment */
printf("%d\n", count);
return 0;
}# Single-line comment
=begin
Multi-line
comment
=end
count = 0 # inline comment
puts countConsecutive
# lines are the idiomatic Ruby style for multi-line comments. The =begin/=end markers must be at the very beginning of the line.Output — puts, print, p
Ruby has three main output methods:
puts adds a newline, print does not, and p shows the value's structure for debugging.#include <stdio.h>
int main(void) {
printf("Hello\n"); // with newline
printf("no newline"); // without newline
printf("x = %d\n", 42); // formatted
fprintf(stderr, "error\n"); // to stderr
return 0;
}puts "Hello" # with newline
print "no newline" # without newline
puts # blank line
puts "x = #{42}" # interpolation
p "hello" # inspect: shows "hello" with quotes
p [1, 2, 3] # inspect: shows [1, 2, 3]p calls .inspect on its argument, showing quotes on strings and brackets on arrays — invaluable for debugging. Unlike printf, Ruby uses string interpolation (#{expression}) instead of format specifiers for most output.Variables & Types
No type declarations
Ruby variables are created on first assignment — no type declaration, no
int, no double, no char[].#include <stdio.h>
int main(void) {
int count = 42;
double price = 9.99;
char name[] = "Alice";
printf("%d %.2f %s\n", count, price, name);
return 0;
}count = 42
price = 9.99
name = "Alice"
puts "#{count} #{price} #{name}"The runtime tracks types automatically, and variable names use
snake_case by convention. There is no distinction between stack-allocated primitives and heap-allocated objects — everything in Ruby is an object.Dynamic typing — variables can change type
In Ruby, variables are not bound to a type — only objects are. Reassigning a variable to a different type is perfectly valid.
#include <stdio.h>
int main(void) {
/* C: type is fixed at declaration */
int value = 42;
/* value = "hello"; // compile error */
printf("%d\n", value);
return 0;
}# Ruby: a variable can hold any type at any time
value = 42
puts value.class # Integer
value = "hello"
puts value.class # String
value = [1, 2, 3]
puts value.class # ArrayThe
.class method returns the actual runtime class of any object. This is fundamentally different from C, where a variable's type is fixed at declaration and enforced by the compiler.Constants
Ruby constants start with an uppercase letter — real, scoped runtime values, not C's textual
#define substitution.#include <stdio.h>
#define MAX_RETRIES 3
#define API_URL "https://example.com"
int main(void) {
printf("%d\n", MAX_RETRIES);
printf("%s\n", API_URL);
return 0;
}MAX_RETRIES = 3
API_URL = "https://example.com"
puts MAX_RETRIES
puts API_URLSCREAMING_SNAKE_CASE is the convention for simple values, and constants respect module/class scope. Reassigning a constant produces a warning but is not a fatal error.nil — not NULL
Ruby's
nil is a real object of class NilClass — not an invalid memory address, and never a segfault.#include <stdio.h>
#include <stddef.h>
int main(void) {
char *pointer = NULL;
if (pointer == NULL) {
printf("pointer is null\n");
}
/* Dereferencing NULL → segfault */
return 0;
}pointer = nil
puts pointer.nil? # true
puts pointer.class # NilClass
puts pointer.to_s # "" (empty string — no segfault)
puts pointer.to_a.inspect # [] (empty array)
puts pointer.to_i # 0Calling a method that
nil does not understand raises a clean NoMethodError. Conversion methods like nil.to_s, nil.to_a, and nil.to_i all return sensible empty values.Truthiness — only nil and false are falsy
Watch out: exactly two Ruby values are falsy —
nil and false. Everything else is truthy, including 0, "", and [].#include <stdio.h>
int main(void) {
/* C: 0, NULL, '