Title: Ruby Programming — LearnCoachAssist

Q: What is a Symbol in Ruby?
A: A Symbol is a lightweight, immutable identifier prefixed with a colon, e.g. :name. Symbols are stored in memory only once, making them more efficient than strings for keys and identifiers.
Example: :status, :id

Q: How do you create an Array in Ruby?
A: An Array is an ordered collection created with square brackets or Array.new.
Examples:
nums = [1, 2, 3]
words = %w[hello world]
empty = Array.new(5, 0)

Q: How do you create a Hash in Ruby?
A: A Hash is a collection of key-value pairs.
Examples:
h = { name: "Alice", age: 30 }
h = Hash.new(0)
Access values with h[:name].

Q: What is a block in Ruby?
A: A block is an anonymous chunk of code enclosed in do...end or curly braces { } that can be passed to a method.
Example:
[1,2,3].each { |n| puts n }

Q: What is the difference between do...end and curly braces for blocks?
A: Both define blocks, but curly braces { } have higher precedence than do...end.
Convention: use { } for single-line blocks and do...end for multi-line blocks.

Q: What is a Proc in Ruby?
A: A Proc is an object that encapsulates a block of code, allowing it to be stored in a variable and called later.
Example:
greet = Proc.new { |name| puts "Hello, #{name}" }
greet.call("Alice")

Q: What is a Lambda in Ruby?
A: A Lambda is a special type of Proc that enforces the correct number of arguments and returns control to the calling method.
Example:
square = ->(x) { x * x }
square.call(5) # => 25

Q: What are the differences between a Proc and a Lambda?
A: Key differences:
- Argument checking: Lambdas raise an error on wrong argument count; Procs assign nil to missing args.
- Return behavior: return in a Lambda exits the lambda; return in a Proc exits the enclosing method.

Q: How do you define a class in Ruby?
A: Use the class keyword:
class Dog
  def initialize(name)
    @name = name
  end
  def bark
    "Woof!"
  end
end

Q: What is the initialize method in a Ruby class?
A: initialize is the constructor method called automatically when you create a new object with ClassName.new. It is used to set up instance variables.
Example: def initialize(name)
  @name = name
end

Q: What are instance variables in Ruby?
A: Instance variables start with @ and belong to a specific object instance. They persist for the lifetime of the object.
Example: @name = "Ruby"

Q: What are class variables in Ruby?
A: Class variables start with @@ and are shared among all instances of a class and its subclasses.
Example:
@@count = 0
Use with caution as subclasses share the same variable.

Q: What is inheritance in Ruby?
A: Inheritance lets a class derive behavior from a parent class using <.
Example:
class Dog < Animal
  def speak
    "Woof"
  end
end
Ruby supports single inheritance only.

Q: What is a Module in Ruby?
A: A Module is a container for methods and constants that cannot be instantiated. Modules serve two purposes:
- Namespacing: grouping related classes/methods.
- Mixins: sharing behavior across classes via include or extend.

Q: What is a Mixin in Ruby?
A: A Mixin is a module included in a class to add shared behavior, providing a form of multiple inheritance.
Example:
module Greetable
  def greet
    "Hello!"
  end
end
class User
  include Greetable
end

Q: What is the difference between include and extend in Ruby?
A: include adds module methods as instance methods of the class.
extend adds module methods as class methods.
Example:
class Foo
  include MyModule  # instance methods
  extend MyModule   # class methods
end

Q: What is the each iterator in Ruby?
A: each is the most common iterator. It passes each element of a collection to a block.
Example:
[10, 20, 30].each { |n| puts n }
It returns the original collection.

Q: What does the map method do in Ruby?
A: map (alias collect) returns a new array with the results of running the block for every element.
Example:
[1,2,3].map { |n| n * 2 }
# => [2, 4, 6]

Q: What does the select method do in Ruby?
A: select returns a new array containing elements for which the block returns true.
Example:
[1,2,3,4,5].select { |n| n.even? }
# => [2, 4]

Q: What does the reduce method do in Ruby?
A: reduce (alias inject) combines all elements by applying a binary operation, accumulating a single result.
Example:
[1,2,3,4].reduce(0) { |sum, n| sum + n }
# => 10

Q: How do you handle exceptions in Ruby?
A: Use begin...rescue...end:
begin
  risky_operation
rescue StandardError => e
  puts e.message
ensure
  cleanup
end
The ensure block always executes.

Q: What is the purpose of the ensure block in exception handling?
A: The ensure block runs regardless of whether an exception was raised or not. It is used for cleanup tasks like closing files or releasing resources.
Example:
begin
  file = File.open("data.txt")
rescue
  puts "Error"
ensure
  file&.close
end

Q: How do you raise a custom exception in Ruby?
A: Create a class inheriting from StandardError:
class MyError < StandardError; end
raise MyError, "Something went wrong"
Catch it with rescue MyError => e.

Q: How do you read a file in Ruby?
A: Use File.read or File.open with a block:
content = File.read("file.txt")
Or line by line:
File.foreach("file.txt") { |line| puts line }
Using a block with File.open automatically closes the file.

Q: How do you write to a file in Ruby?
A: Use File.open with the "w" mode:
File.open("out.txt", "w") do |f|
  f.puts "Hello, world!"
end
Use "a" mode to append instead of overwriting.

Q: What are regular expressions in Ruby?
A: Regular expressions (regex) are patterns enclosed in forward slashes used for matching strings.
Example:
/\d+/.match("abc123")
# => #<MatchData "123">
Use =~ operator: "hello" =~ /ell/ # => 1

Q: How do you use gsub with a regex in Ruby?
A: gsub replaces all occurrences matching a pattern:
"hello world".gsub(/[aeiou]/, "*")
# => "h*ll* w*rld"
You can also pass a block:
"cat bat".gsub(/\b\w/) { |m| m.upcase }

Q: What is a Gem in Ruby?
A: A Gem is a packaged Ruby library or application distributed via RubyGems.
Install with: gem install rails
Manage project dependencies with a Gemfile and Bundler:
bundle install

Q: What is Bundler in Ruby?
A: Bundler manages gem dependencies for a Ruby project. It reads the Gemfile, resolves versions, and generates a Gemfile.lock.
Commands:
- bundle install — install dependencies
- bundle exec — run commands in the bundle context

Q: What is metaprogramming in Ruby?
A: Metaprogramming is writing code that writes or modifies code at runtime. Ruby supports it extensively with methods like define_method, method_missing, and send.
It allows dynamic creation of methods, classes, and modules.

Q: What does method_missing do in Ruby?
A: method_missing is called when an object receives a message it cannot handle. You can override it to intercept undefined method calls.
Example:
def method_missing(name, *args)
  puts "Called: #{name}"
end
Always define respond_to_missing? alongside it.

Q: What does define_method do in Ruby?
A: define_method dynamically creates an instance method at runtime.
Example:
class Dog
  ["sit", "stay"].each do |cmd|
    define_method(cmd) { puts cmd }
  end
end
Dog.new.sit # => "sit"

Q: What does send do in Ruby?
A: send invokes a method by name (as a symbol or string), including private methods.
Example:
obj.send(:my_method, arg1)
Use public_send to restrict to public methods only for safety.

Q: What is open_struct in Ruby?
A: OpenStruct (from the ostruct library) creates objects with arbitrary attributes defined at runtime.
Example:
require "ostruct"
person = OpenStruct.new(name: "Alice", age: 30)
person.name # => "Alice"

Q: What is the yield keyword in Ruby?
A: yield transfers control from a method to the block passed to it.
Example:
def greet
  yield("World") if block_given?
end
greet { |name| puts "Hello, #{name}!" }

Q: What does block_given? do in Ruby?
A: block_given? returns true if a block was passed to the current method, false otherwise. It prevents a LocalJumpError when calling yield without a block.
Example:
def safe_call
  yield if block_given?
end

Q: What is the ampersand (&) operator for blocks?
A: The & operator converts between blocks and Procs:
- &block in a parameter captures a block as a Proc.
- &proc in a method call converts a Proc into a block.
Example:
def run(&blk)
  blk.call
end

Q: What are attr_accessor, attr_reader, and attr_writer?
A: These are class macros that generate getter/setter methods:
- attr_reader :name — getter only
- attr_writer :name — setter only
- attr_accessor :name — both getter and setter
They replace manually defining def name and def name=.

Q: What is the freeze method in Ruby?
A: freeze makes an object immutable. Any attempt to modify a frozen object raises a FrozenError.
Example:
str = "hello"
str.freeze
str << " world" # => FrozenError
Check with str.frozen?.

Q: What is the difference between == and eql? and equal? in Ruby?
A: - == — checks value equality (can be overridden).
- eql? — checks value and type equality (used by Hash for keys).
- equal? — checks object identity (same object_id).
Example: 1 == 1.0 # true, 1.eql?(1.0) # false

Q: What is the Comparable module in Ruby?
A: The Comparable module provides comparison operators (<, <=, ==, >=, >) when you define the <=> (spaceship) method.
Example:
class Box
  include Comparable
  def <=>(other)
    self.size <=> other.size
  end
end

Q: What is the Enumerable module in Ruby?
A: Enumerable provides collection methods like map, select, reduce, sort, and min. Include it in your class and define an each method to gain all these methods automatically.

Q: What are frozen string literals in Ruby?
A: Adding # frozen_string_literal: true at the top of a Ruby file makes all string literals immutable by default. This improves performance by reducing object allocations and is a recommended practice in modern Ruby.

Q: What is the ternary operator in Ruby?
A: The ternary operator is a concise conditional expression:
condition ? true_value : false_value
Example:
status = age >= 18 ? "adult" : "minor"

Q: What is the difference between puts, print, and p in Ruby?
A: - puts — prints with a newline, calls .to_s.
- print — prints without a newline, calls .to_s.
- p — prints the .inspect output with a newline (useful for debugging).
Example: p [1,2] outputs [1, 2].

Q: How do you use string interpolation in Ruby?
A: Embed expressions inside double-quoted strings with #{}:
name = "Ruby"
puts "Hello, #{name}!"
# => Hello, Ruby!
Single-quoted strings do not support interpolation.

Q: What is the splat operator (*) in Ruby?
A: The splat operator * collects or expands arguments:
- Collect: def foo(*args) gathers extra arguments into an array.
- Expand: method(*array) passes array elements as separate arguments.
Double splat ** works the same way for keyword arguments.

Q: What is the safe navigation operator (&.) in Ruby?
A: The safe navigation operator &. calls a method only if the receiver is not nil, returning nil otherwise.
Example:
user&.name
This avoids NoMethodError on nil objects. Equivalent to user && user.name.

Q: How do you use the case/when statement in Ruby?
A: case provides pattern-matching control flow:
case grade
when "A" then "Excellent"
when "B" then "Good"
when "C" then "Average"
else "Needs improvement"
end
It uses the === operator, so it works with ranges, classes, and regex too.

Q: How do you create a Range in Ruby?
A: A Range represents an interval of values using .. (inclusive) or ... (exclusive).
Examples:
(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]
Ranges work with numbers, strings, and any object implementing <=>.