🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples Ruby
Exemples de code Ruby essentiels pour le développement web, incluant le framework Rails et les fonctionnalités modernes de Ruby
💻 Hello World Ruby ruby
🟢 simple
⭐
Programme Hello World de base avec typage dynamique et syntaxe élégante
⏱️ 12 min
🏷️ ruby, dynamic typing, object-oriented
Prerequisites:
Basic programming concepts
# Ruby Hello World Examples
# 1. Basic Hello World
puts "Hello, World!"
# 2. Hello World with variable
message = "Hello, World!"
puts message
# 3. Hello World with method
def say_hello
"Hello, World!"
end
puts say_hello
# 4. Hello World with parameters
def greet(name)
"Hello, #{name}!"
end
puts greet("World")
puts greet("Ruby")
# 5. Hello World with class
class Greeter
def initialize(message = "Hello, World!")
@message = message
end
def greet
puts @message
end
end
greeter = Greeter.new
greeter.greet
# 6. Hello World with user input
print "Enter your name: "
name = gets.chomp
puts "Hello, #{name}!"
# 7. Hello World multiple times
5.times do |i|
puts "Hello, World! #{i + 1}"
end
# 8. Hello World with array
greetings = ["Hello", "Bonjour", "Hola", "Ciao", "こんにちは"]
greetings.each do |greeting|
puts "#{greeting}, World!"
end
# 9. Hello World with hash
greetings = {
"en" => "Hello",
"es" => "Hola",
"fr" => "Bonjour",
"de" => "Hallo",
"ja" => "こんにちは"
}
greetings.each do |lang, greeting|
puts "#{greeting}, World! (#{lang})"
end
# 10. Hello World with JSON
require 'json'
response = {
message: "Hello, World!",
timestamp: Time.now.to_s,
success: true
}
puts JSON.pretty_generate(response)
# Basic data types examples
# Ruby is dynamically typed, so types are inferred
integer = 42
float = 3.14
string = "Hello, Ruby!"
boolean = true
array = [1, 2, 3, 4, 5]
hash = { name: "John Doe", age: 30, email: "[email protected]" }
symbol = :ruby_symbol
nil_value = nil
puts "Integer: #{integer}, Class: #{integer.class}"
puts "Float: #{float}, Class: #{float.class}"
puts "String: #{string}, Class: #{string.class}"
puts "Boolean: #{boolean}, Class: #{boolean.class}"
puts "Array: #{array}, Class: #{array.class}"
puts "Hash: #{hash}, Class: #{hash.class}"
puts "Symbol: #{symbol}, Class: #{symbol.class}"
puts "Nil: #{nil_value}, Class: #{nil_value.class}"
# Control flow examples
age = 18
if age >= 18
puts "You are an adult"
else
puts "You are a minor"
end
# Case statement
grade = 'A'
case grade
when 'A'
puts "Excellent!"
when 'B'
puts "Good job!"
when 'C'
puts "Fair enough"
else
puts "Need improvement"
end
# Loop examples
fruits = ["apple", "banana", "cherry"]
fruits.each do |fruit|
puts "I like #{fruit}"
end
# Range operations
(1..10).each do |i|
puts "Number: #{i}"
end
# Array methods examples
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = numbers.select { |n| n.even? }
squared_numbers = numbers.map { |n| n ** 2 }
sum = numbers.reduce(0, :+)
puts "Even numbers: #{even_numbers}"
puts "Squared numbers: #{squared_numbers}"
puts "Sum: #{sum}"
# String methods examples
text = "Hello, Ruby Programming!"
puts "Upcase: #{text.upcase}"
puts "Downcase: #{text.downcase}"
puts "Capitalized: #{text.capitalize}"
puts "Length: #{text.length}"
puts "Reverse: #{text.reverse}"
# Method chaining
numbers = [1, 2, 3, 4, 5]
result = numbers
.select { |n| n.even? }
.map { |n| n ** 2 }
.reduce(0, :+)
puts "Result of chained operations: #{result}"
# Blocks and Procs
def execute_twice
yield
yield
end
execute_twice { puts "Hello from block!" }
# Procs and Lambdas
greet_proc = Proc.new { |name| puts "Hello, #{name}!" }
greet_proc.call("Ruby")
greet_lambda = lambda { |name| "Hello, #{name}!" }
puts greet_lambda.call("Lambda")
# Symbols and their common uses
status = :active
puts status == :active ? "User is active" : "User is inactive"
# Using symbols as hash keys (Rubyist style)
user = {
name: "Alice",
age: 25,
:email => "[email protected]"
}
puts user[:name]
puts user[:email]
# Constants
PI = 3.14159265359
MAX_USERS = 100
puts "PI: #{PI}"
puts "Max users: #{MAX_USERS}"
# Exception handling
begin
result = 10 / 0
rescue ZeroDivisionError => e
puts "Error: #{e.message}"
ensure
puts "This always runs"
end
# Method return values
def add(a, b)
# Ruby implicitly returns the last evaluated expression
a + b
end
puts "Addition: #{add(5, 3)}"
# Splat arguments
def sum(*numbers)
numbers.reduce(0, :+)
end
puts "Sum of 1, 2, 3, 4, 5: #{sum(1, 2, 3, 4, 5)}"
# Keyword arguments (Ruby 2.0+)
def create_user(name:, email:, age: nil, role: 'user')
{
name: name,
email: email,
age: age,
role: role
}
end
user = create_user(name: "Bob", email: "[email protected]", age: 30)
puts "Created user: #{user}"
# Class methods
class MathUtils
def self.pi
3.14159265359
end
def self.circle_area(radius)
pi * radius ** 2
end
end
puts "Pi: #{MathUtils.pi}"
puts "Circle area (radius 5): #{MathUtils.circle_area(5)}"
# Modules and mixins
module Greetable
def greet
puts "Hello, I'm #{name}"
end
end
class Person
include Greetable
attr_reader :name
def initialize(name)
@name = name
end
end
person = Person.new("Charlie")
person.greet
💻 Patrons Ruby on Rails ruby
🟡 intermediate
⭐⭐⭐⭐
Patrons Rails courants, architecture MVC et pratiques modernes de développement web
⏱️ 45 min
🏷️ ruby, rails, web development, patterns
Prerequisites:
Ruby basics, Web development concepts, MVC architecture
# Ruby on Rails Patterns Examples
# 1. Model with validations and associations
# app/models/user.rb
class User < ApplicationRecord
# Validations
validates :name, presence: true, length: { minimum: 2, maximum: 50 }
validates :email, presence: true, uniqueness: { case_sensitive: false }
validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :age, numericality: { greater_than: 0, less_than: 120 }
validates :terms_of_service, acceptance: true
# Callbacks
before_save :downcase_email
after_create :send_welcome_email
after_commit :log_user_creation
# Associations
has_many :posts, dependent: :destroy
has_many :comments, through: :posts
has_one :profile, dependent: :destroy
has_and_belongs_to_many :roles
has_many :followers, class_name: "Follow", foreign_key: "followed_id"
has_many :followed, class_name: "Follow", foreign_key: "follower_id"
# Scopes
scope :active, -> { where(active: true) }
scope :by_age, ->(min_age, max_age) { where(age: min_age..max_age) }
scope :recent, -> { order(created_at: :desc) }
scope :with_posts, -> { includes(:posts).where.not(posts: { id: nil }) }
# Class methods
def self.search(query)
where("name ILIKE ? OR email ILIKE ?", "%#{query}%", "%#{query}%")
end
def self.by_role(role_name)
joins(:roles).where(roles: { name: role_name })
end
# Instance methods
def full_name
profile&.full_name || name
end
def admin?
roles.exists?(name: 'admin')
end
def can_post?
active? && email_verified?
end
def follow(user)
followed << user unless following?(user)
end
def unfollow(user)
followed.delete(user) if following?(user)
end
def following?(user)
followed.include?(user)
end
private
def downcase_email
email.downcase!
end
def send_welcome_email
UserMailer.welcome_email(self).deliver_later
end
def log_user_creation
Rails.logger.info "New user created: #{name} (#{email})"
end
end
# 2. Controller with RESTful actions and strong parameters
# app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!
before_action :set_user, only: [:show, :edit, :update, :destroy]
before_action :authorize_user, only: [:edit, :update, :destroy]
# GET /users
def index
@users = User.includes(:profile)
.active
.recent
.page(params[:page])
.per(20)
respond_to do |format|
format.html
format.json { render json: @users }
format.csv { send_data User.to_csv(@users), filename: "users.csv" }
end
end
# GET /users/1
def show
@posts = @user.posts.includes(:comments).published.recent.limit(10)
respond_to do |format|
format.html
format.json { render json: @user }
end
end
# GET /users/new
def new
@user = User.new
@user.build_profile
end
# POST /users
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render json: @user, status: :created }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
# GET /users/1/edit
def edit
end
# PATCH/PUT /users/1
def update
respond_to do |format|
if @user.update(user_params)
format.html { redirect_to @user, notice: 'User was successfully updated.' }
format.json { render json: @user }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
def destroy
@user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_user
@user = User.includes(:profile, :posts).find(params[:id])
end
def authorize_user
redirect_to root_path, alert: 'Not authorized' unless can?(:manage, @user)
end
def user_params
params.require(:user).permit(
:name,
:email,
:age,
:bio,
profile_attributes: [
:id,
:first_name,
:last_name,
:avatar,
:website,
:location,
:bio
]
)
end
end
# 3. Service Object Pattern
# app/services/user_registration_service.rb
class UserRegistrationService
include ActiveModel::Model
include ActiveModel::Attributes
attribute :email, :string
attribute :password, :string
attribute :password_confirmation, :string
attribute :name, :string
attribute :accept_terms, :boolean
attribute :marketing_emails, :boolean, default: false
validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :password, presence: true, length: { minimum: 8 }
validates :password_confirmation, presence: true
validates :name, presence: true, length: { minimum: 2 }
validates :accept_terms, acceptance: true
validate :passwords_match
validate :email_uniqueness
def call
return false unless valid?
ActiveRecord::Base.transaction do
user = User.create!(user_attributes)
Profile.create!(profile_attributes(user))
send_welcome_email(user)
subscribe_to_newsletter(user) if marketing_emails
user
end
rescue ActiveRecord::RecordInvalid => e
errors.add(:base, e.message)
false
end
private
def passwords_match
return if password == password_confirmation
errors.add(:password_confirmation, "doesn't match Password")
end
def email_uniqueness
return unless User.exists?(email: email)
errors.add(:email, "has already been taken")
end
def user_attributes
{
email: email.downcase,
password: password,
name: name,
active: true,
email_verified: false
}
end
def profile_attributes(user)
{
user: user,
first_name: name.split(' ').first,
last_name: name.split(' ').last,
avatar: generate_default_avatar,
email_notifications: true
}
end
def generate_default_avatar
# Generate a default avatar using a service like Gravatar
"https://ui-avatars.com/api/?name=#{URI.encode_www_form_component(name)}&background=random"
end
def send_welcome_email(user)
UserMailer.welcome_email(user).deliver_later
end
def subscribe_to_newsletter(user)
NewsletterSubscription.create!(user: user, active: true)
end
end
# 4. Decorator Pattern
# app/decorators/user_decorator.rb
class UserDecorator
include ActionView::Helpers
include Rails.application.routes.url_helpers
def initialize(user)
@user = user
end
delegate_missing_to :@user
def display_name
if profile&.first_name && profile&.last_name
"#{profile.first_name} #{profile.last_name}"
else
name
end
end
def avatar_url(size: :medium)
if profile&.avatar.present?
profile.avatar.variant(resize: avatar_size(size))
else
default_avatar_url
end
end
def profile_completion_percentage
completed_fields = 0
total_fields = 5
completed_fields += 1 if name.present?
completed_fields += 1 if email.present?
completed_fields += 1 if profile&.bio.present?
completed_fields += 1 if profile&.location.present?
completed_fields += 1 if profile&.website.present?
(completed_fields.to_f / total_fields * 100).round
end
def join_date
created_at.strftime("%B %d, %Y")
end
def status_badge
case
when admin?
content_tag(:span, "Admin", class: "badge badge-danger")
when active?
content_tag(:span, "Active", class: "badge badge-success")
else
content_tag(:span, "Inactive", class: "badge badge-secondary")
end
end
def stats
{
posts: posts.published.count,
comments: comments.count,
followers: followers.count,
following: followed.count
}
end
def action_buttons(current_user)
buttons = []
if current_user == self
buttons << link_to("Edit Profile", edit_user_path(self), class: "btn btn-primary")
else
if current_user.following?(self)
buttons << link_to("Unfollow", unfollow_user_path(self), method: :delete, class: "btn btn-secondary")
else
buttons << link_to("Follow", follow_user_path(self), method: :post, class: "btn btn-primary")
end
end
buttons.join(" ").html_safe
end
private
def avatar_size(size)
case size
when :small then "50x50"
when :medium then "100x100"
when :large then "200x200"
else "100x100"
end
end
def default_avatar_url
"https://ui-avatars.com/api/?name=#{URI.encode_www_form_component(name)}&background=random&size=100"
end
end
# 5. Query Object Pattern
# app/queries/post_search_query.rb
class PostSearchQuery
def initialize(params = {})
@params = params
end
def call
posts = Post.published.includes(:user, :tags, :comments)
posts = filter_by_user(posts)
posts = filter_by_tags(posts)
posts = filter_by_date_range(posts)
posts = filter_by_status(posts)
posts = search_by_content(posts)
posts = sort_posts(posts)
posts
end
private
attr_reader :params
def filter_by_user(posts)
return posts unless params[:user_id].present?
posts.where(user_id: params[:user_id])
end
def filter_by_tags(posts)
return posts unless params[:tag_ids].present?
posts.joins(:tags).where(tags: { id: params[:tag_ids] })
end
def filter_by_date_range(posts)
if params[:date_from].present?
posts = posts.where("posts.created_at >= ?", params[:date_from])
end
if params[:date_to].present?
posts = posts.where("posts.created_at <= ?", params[:date_to])
end
posts
end
def filter_by_status(posts)
return posts unless params[:status].present?
posts.where(status: params[:status])
end
def search_by_content(posts)
return posts unless params[:query].present?
posts.where(
"posts.title ILIKE ? OR posts.content ILIKE ?",
"%#{params[:query]}%",
"%#{params[:query]}%"
)
end
def sort_posts(posts)
sort_column = params[:sort] || 'created_at'
sort_direction = params[:direction] || 'desc'
if posts.column_names.include?(sort_column)
posts.order("#{sort_column} #{sort_direction}")
else
posts.order(created_at: :desc)
end
end
end
# 6. Form Object Pattern
# app/forms/post_form.rb
class PostForm
include ActiveModel::Model
include ActiveModel::Attributes
include ActiveModel::Validations::Callbacks
attribute :title, :string
attribute :content, :string
attribute :excerpt, :string
attribute :status, :string, default: 'draft'
attribute :published_at, :datetime
attribute :tag_names, :string, default: ''
attribute :featured_image, :string
attribute :user_id, :integer
validates :title, presence: true, length: { maximum: 100 }
validates :content, presence: true, length: { minimum: 50 }
validates :status, inclusion: { in: %w[draft published archived] }
validates :user_id, presence: true
validate :published_at_presence_if_published
validate :tag_names_validity
before_validation :generate_excerpt_if_blank
before_validation :set_published_at
def initialize(post = nil, attributes = {})
@post = post
super(attributes)
copy_post_attributes if @post
end
def save
return false unless valid?
ActiveRecord::Base.transaction do
post = @post || user.posts.build
post.assign_attributes(post_attributes)
post.save!
update_post_tags(post)
@post = post
end
true
rescue ActiveRecord::RecordInvalid => e
errors.add(:base, e.message)
false
end
def persisted?
@post&.persisted?
end
private
attr_reader :post
def user
User.find(user_id) if user_id.present?
end
def post_attributes
{
title: title,
content: content,
excerpt: excerpt,
status: status,
published_at: published_at,
featured_image: featured_image
}
end
def copy_post_attributes
self.title = @post.title
self.content = @post.content
self.excerpt = @post.excerpt
self.status = @post.status
self.published_at = @post.published_at
self.featured_image = @post.featured_image
self.user_id = @post.user_id
self.tag_names = @post.tags.map(&:name).join(', ')
end
def published_at_presence_if_published
return unless status == 'published'
errors.add(:published_at, "can't be blank when status is published") if published_at.blank?
end
def tag_names_validity
return if tag_names.blank?
invalid_tags = tag_names.split(',').map(&:strip).reject { |name| name.match?(/A[a-zA-Z0-9s-]+z/) }
if invalid_tags.any?
errors.add(:tag_names, "contain invalid tags: #{invalid_tags.join(', ')}")
end
end
def generate_excerpt_if_blank
return if excerpt.present?
self.excerpt = content&.truncate(150, separator: ' ')
end
def set_published_at
self.published_at = Time.current if status == 'published' && published_at.blank?
end
def update_post_tags(post)
tag_names_array = tag_names.split(',').map(&:strip).map(&:downcase).uniq
current_tag_names = post.tags.map(&:name)
# Remove tags that are no longer present
tags_to_remove = current_tag_names - tag_names_array
post.tags.where(name: tags_to_remove).destroy_all if tags_to_remove.any?
# Add new tags
tag_names_array.each do |tag_name|
next if current_tag_names.include?(tag_name)
post.tags.find_or_create_by(name: tag_name)
end
end
end
# 7. Background Job Pattern
# app/jobs/email_notification_job.rb
class EmailNotificationJob < ApplicationJob
queue_as :default
rescue_from(StandardError) do |exception|
Rails.logger.error "Email job failed: #{exception.message}"
retry_job wait: 5.minutes, attempts: 3
end
def perform(user_id, template, **options)
user = User.find(user_id)
UserMailer.with(user: user, **options).send(template).deliver_now
end
end
# 8. Policy Pattern for Authorization
# app/policies/post_policy.rb
class PostPolicy
attr_reader :user, :post
def initialize(user, post)
@user = user
@post = post
end
def index?
true
end
def show?
post.published? || (user && (user.admin? || user == post.user))
end
def create?
user.present? && user.can_post?
end
def update?
user.present? && (user.admin? || user == post.user)
end
def destroy?
user.present? && (user.admin? || user == post.user)
end
def publish?
user.present? && (user.admin? || (user == post.user && user.can_post?))
end
class Scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user&.admin?
scope.all
elsif user.present?
scope.where("published = ? OR user_id = ?", true, user.id)
else
scope.where(published: true)
end
end
private
attr_reader :user, :scope
end
end
# Example usage in controller:
# def index
# @posts = policy_scope(Post)
# @posts = PostSearchQuery.new(params).call
# end
# def show
# authorize @post
# end
💻 Métaprogrammation Ruby ruby
🔴 complex
⭐⭐⭐⭐⭐
Techniques avancées de métaprogrammation, méthodes dynamiques et méthodes magiques Ruby
⏱️ 50 min
🏷️ ruby, metaprogramming, advanced, dynamic
Prerequisites:
Advanced Ruby, Object-oriented Ruby, Ruby introspection
# Ruby Metaprogramming Examples
# 1. Dynamic method definition
class DynamicMethods
def self.create_methods(*method_names)
method_names.each do |name|
define_method(name) do |arg|
"Called method #{name} with argument: #{arg}"
end
end
end
end
DynamicMethods.create_methods(:foo, :bar, :baz)
obj = DynamicMethods.new
puts obj.foo("hello")
puts obj.bar("world")
puts obj.baz("ruby")
# 2. method_missing for dynamic method calls
class DynamicAccessor
def initialize(data = {})
@data = data
end
def method_missing(method_name, *args, &block)
if method_name.to_s.end_with?('=')
# Setter method
key = method_name.to_s.chomp('=').to_sym
@data[key] = args.first
else
# Getter method
key = method_name.to_sym
if @data.key?(key)
@data[key]
else
super
end
end
end
def respond_to_missing?(method_name, include_private = false)
method_name.to_s.end_with?('=') || @data.key?(method_name.to_sym) || super
end
end
accessor = DynamicAccessor.new
accessor.name = "John"
accessor.age = 30
puts accessor.name
puts accessor.age
# 3. Class-level metaprogramming
class ActiveRecord
@@attributes = {}
def self.attribute(name, type = :string)
@@attributes[name] = type
define_method(name) do
@attributes[name]
end
define_method("#{name}=") do |value|
@attributes[name] = cast_type(value, type)
end
end
def self.attributes
@@attributes
end
def initialize
@attributes = {}
end
private
def cast_type(value, type)
case type
when :string
value.to_s
when :integer
value.to_i
when :float
value.to_f
when :boolean
!!value
else
value
end
end
end
class User < ActiveRecord
attribute :name, :string
attribute :age, :integer
attribute :email, :string
attribute :active, :boolean
end
user = User.new
user.name = "Alice"
user.age = 25
user.email = "[email protected]"
user.active = true
puts "Name: #{user.name}, Age: #{user.age}, Active: #{user.active}"
# 4. Module metaprogramming
class MacroModule
def self.delegated_methods(*methods, to:)
methods.each do |method|
define_method(method) do |*args, &block|
send(to).send(method, *args, &block)
end
end
end
end
class Person
MacroModule.delegated_methods :name, :email, to: :@contact_info
def initialize
@contact_info = OpenStruct.new
end
end
require 'ostruct'
person = Person.new
person.name = "Bob"
person.email = "[email protected]"
puts person.name
puts person.email
# 5. Singleton methods and eigenclass
obj = Object.new
# Define singleton method
def obj.special_method
"This is a singleton method!"
end
puts obj.special_method
# Define singleton methods using eigenclass
class << obj
def another_special_method
"Another singleton method!"
end
end
puts obj.another_special_method
# 6. Class methods as singleton methods
class MyClass
# This creates a singleton method on the class object
def self.class_method
"This is a class method"
end
# Using eigenclass for class methods
class << self
def another_class_method
"Another class method"
end
end
end
puts MyClass.class_method
puts MyClass.another_class_method
# 7. Dynamic class creation
dynamic_class = Class.new do
def initialize(name)
@name = name
end
def greet
"Hello, #{@name}!"
end
end
instance = dynamic_class.new("Dynamic Class")
puts instance.greet
# 8. Method introspection
class IntrospectionExample
def public_method; end
protected :def protected_method; end
private :def private_method; end
def self.class_method; end
end
obj = IntrospectionExample.new
puts "Public methods: #{obj.public_methods(false).sort}"
puts "Protected methods: #{obj.protected_methods(false).sort}"
puts "Private methods: #{obj.private_methods(false).sort}"
puts "Class methods: #{IntrospectionExample.methods(false).sort}"
# Method information
if obj.respond_to?(:public_method)
puts "Object responds to :public_method"
puts "Method arity: #{obj.method(:public_method).arity}"
end
# 9. Using const_missing for dynamic constants
module DynamicConstants
def self.const_missing(name)
if name.to_s.start_with?('CONFIG_')
# Load configuration dynamically
config_key = name.to_s.sub('CONFIG_', '').downcase
"Configuration for #{config_key}"
else
super
end
end
end
puts DynamicConstants::CONFIG_DATABASE
puts DynamicConstants::CONFIG_API
# 10. Advanced metaprogramming with modules
class AdvancedMetaprogramming
def self.add_validator(attr_name, validator_proc)
define_method("#{attr_name}_valid?") do
value = instance_variable_get("@#{attr_name}")
validator_proc.call(value)
end
end
def self.attr_accessor_with_validation(attr_name, validator_proc)
attr_writer attr_name
define_method(attr_name) do
instance_variable_get("@#{attr_name}")
end
add_validator(attr_name, validator_proc)
end
end
class ValidatedUser
extend AdvancedMetaprogramming
attr_accessor_with_validation :email, ->(value) { value.match?(/A[^@s]+@[^@s]+z/) }
attr_accessor_with_validation :age, ->(value) { value.is_a?(Integer) && value > 0 }
def initialize
@validations = {}
end
def valid?
email_valid? && age_valid?
end
end
user = ValidatedUser.new
user.email = "[email protected]"
user.age = 25
puts "User valid: #{user.valid?}"
# 11. Method chaining with self
class MethodChaining
def initialize
@operations = []
end
def add(value)
@operations << [:add, value]
self
end
def multiply(value)
@operations << [:multiply, value]
self
end
def result
@operations.reduce(0) do |acc, (op, value)|
case op
when :add then acc + value
when :multiply then acc * value
end
end
end
end
result = MethodChaining.new.add(5).multiply(2).add(3).result
puts "Method chaining result: #{result}"
# 12. Using define_method with blocks
class DynamicBlockMethods
def self.create_math_operation(name, operation)
define_method(name) do |*args|
args.reduce(&operation)
end
end
end
DynamicBlockMethods.create_math_operation(:sum, :+)
DynamicBlockMethods.create_math_operation(:product, :*)
math_ops = DynamicBlockMethods.new
puts "Sum of 1, 2, 3, 4: #{math_ops.sum(1, 2, 3, 4)}"
puts "Product of 2, 3, 4: #{math_ops.product(2, 3, 4)}"
# 13. Instance_eval and class_eval
class EvalExample
def initialize
@value = 10
end
def demonstrate_instance_eval
instance_eval do
puts "Inside instance_eval, @value = #{@value}"
@value = 20
end
puts "After instance_eval, @value = #{@value}"
end
end
class << EvalExample
def demonstrate_class_eval
class_eval do
def class_level_method
"I was added with class_eval"
end
end
end
end
EvalExample.demonstrate_class_eval
obj = EvalExample.new
obj.demonstrate_instance_eval
puts obj.class_level_method
# 14. Method tracing with alias_method
class MethodTracer
def self.trace_methods(*method_names)
method_names.each do |method_name|
original_method = instance_method(method_name)
define_method(method_name) do |*args, &block|
puts "Calling #{method_name} with args: #{args}"
result = original_method.bind(self).call(*args, &block)
puts "#{method_name} returned: #{result}"
result
end
end
end
def add(a, b)
a + b
end
def multiply(a, b)
a * b
end
end
MethodTracer.trace_methods(:add, :multiply)
tracer = MethodTracer.new
puts tracer.add(5, 3)
puts tracer.multiply(4, 6)