Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save valikos/0770088e9f30ea8fcc17136659c0b793 to your computer and use it in GitHub Desktop.
Save valikos/0770088e9f30ea8fcc17136659c0b793 to your computer and use it in GitHub Desktop.
metaprogramming-examples
# refinements.rb
module TimeExtensions
refine Integer do
def minutes; self * 60.000001; end
end
end
class MyApp
using TimeExtensions
def initialize
p 2.minutes
end
end
MyApp.new
p 3.minutes
# method_binding.rb
class MyClass
def initialize(value)
@x = value
end
def my_method
@x
end
end
class MyClass2 < MyClass
end
object = MyClass.new(1)
m = object.method(:my_method)
m.call # => 1
unbound = m.unbind
another_object = MyClass2.new(2)
m = unbound.bind(another_object)
m.call
# template_engine.rb
class Template
def initialize(locals, &block)
@template = ''
@indent = 0
m = Module.new do
locals.each do |(k, v)|
define_method(k) { v }
end
end
extend(m)
instance_eval(&block)
end
def text(string)
@template += indent(string) + "\n"
end
def method_missing(name, attributes = {})
attributes_string =
attributes.reduce('') { |acc, (k, v)| acc + " #{k}=#{v}" }
@template += indent("<#{name}#{attributes_string}>\n")
@indent += 2
yield
@indent -= 2
@template += indent("</#{name}>\n")
end
def indent(str)
' ' * @indent + str
end
def to_s
@template
end
end
records = 5.times.map do |i|
Struct
.new(:url, :title)
.new("articles/#{i + 1}", "Article #{i + 1}")
end
template = Template.new(articles: records) do
div class: 'wrapper', id: 'wrapper' do
h1 class: 'title' do
text 'Hello world'
end
ul do
articles.each do |article|
li do
a href: article.url do
text article.title
end
end
end
end
end
end
puts template.to_s
File.write('index.html', template.to_s)
# module-extensions.rb
module M
module ClassMethods
def find(str)
'hello ' + str
end
end
module InstanceMethods
def age
25
end
end
def self.included(klass)
klass.include InstanceMethods
klass.extend ClassMethods
end
end
class Person
include M
end
puts Person.find('world')
puts Person.new.age
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment