SlideShare a Scribd company logo
Metaprogramação
na prática
Guilherme Carreiro
TDC Florianópolis - 16.05.2015
Guilherme Carreiro
Campinas, SP
Ruby, JavaScript, Java
dextra/projects
karreiro/picuture_from
discourse/OneBox
TDC 2015 - Metaprogramação na prática
Guilherme Carreiro
Campinas, SP
Ruby, JavaScript, Java
dextra/projects
karreiro/picuture_from
discourse/OneBox
TDC 2015 - Metaprogramação na prática
eval('`rm -rf /`')
class User < ActiveRecord::Base
# empty
end
user = User.new(name: 'Guilherme', active: true)
user.active?
# => true
TDC 2015 - Metaprogramação na prática
Metaprogramming is writing
code that manipulates code
at runtime.
class User < ActiveRecord::Base
# empty
end
user = User.new(name: 'Guilherme', active: true)
user.active?
# => true
class User
attr_accessor :name, :active
end
user = User.new.tap do |u|
u.name = 'Guilherme'
u.active = true
end
user.active?
# => NoMethodError: undefined method `active?' for
#<User:0x007fe5d189a2b0 @name="Guilherme", @active=true>
TDC 2015 - Metaprogramação na prática
#eval
class User
def self.define_methods
attributes = [:name?, :active?]
attributes.each do |attribute|
class_eval <<-EOMETHOD
def #{attribute}
true
end
EOMETHOD
end
end
end
user = User.new
user.name?
# => NoMethodError: undefined method `name?’ for #<User:0x007f...>
User.define_methods
user.name?
# => true
class User
class_eval do
def self.class_name
'~ User ~'
end
end
end
User.class_name
# => "~ User ~”
user = User.new
user.instance_eval do
def self.instance_name
'~ user ~'
end
end
user.instance_name
# => "~ user ~”
class_eval vs. instance_eval
Prefira const_get,
instance_variable_get, ou...
#define_method
class User < ActiveRecord::Base
enum status: { active: 0, archived: 1 }
end
user = User.new
user.status
# => 'archived'
user.active?
# => false
user.active!
# => true
user.active?
# => true
module ActiveRecord
module Enum
# (...)
# Dado que value: 'active', name: 'status' e i: 0
# def active?() status == 0 end
define_method("#{value}?") { self[name] == i }
# def active!() update! status: :active end
define_method("#{value}!") { update! name => value }
# (...)
end
end
class User
attr_accessor :name, :status
def active?
self.status == 'active'
end
def archived?
self.status == 'archived'
end
def deleted?
self.status == 'deleted'
end
end
User.new.tap { |u| u.status = 'active' }.active?
# => true
User.new.tap { |u| u.status = 'active' }.archived?
# => false
User.new.tap { |u| u.status = 'active' }.deleted?
# => false
class User
attr_accessor :name, :status
STATUSES = [:active, :archived, :deleted]
STATUSES.each do |status|
define_method "#{status}?" do
self.status == status.to_s
end
end
end
User.new.tap { |u| u.status = 'active' }.active?
# => true
User.new.tap { |u| u.status = 'active' }.archived?
# => false
User.new.tap { |u| u.status = 'active' }.deleted?
# => false
#method_missing
class User
attr_accessor :name, :active
end
user = User.new.tap do |u|
u.name = 'Guilherme'
u.active = true
end
class CustomRecord
def method_missing(name, *args, &block)
name.to_s.end_with?('?') || super
!!instance_variable_get("@#{name}".gsub /?$/, '')
end
end
class User < CustomRecord
attr_accessor :name, :active
end
user = User.new.tap do |u|
u.name = 'Guilherme'
u.active = true
end
user.active?
# => true
class CustomRecord
def method_missing(name, *args, &block)
name.to_s.end_with?('?') || super
!!instance_variable_get("@#{name}".gsub /?$/, '')
end
end
class User < CustomRecord
attr_accessor :name, :active
end
user = User.new.tap do |u|
u.name = 'Guilherme'
u.active = true
end
user.active?
# => true
user.respond_to? :active?
# => false
class CustomRecord
def method_missing(name, *args, &block)
name.to_s.end_with?('?') || super
!!instance_variable_get("@#{name}".gsub /?$/, '')
end
def respond_to_missing?(name, include_all)
name.to_s.end_with?('?') || super
end
end
class User < CustomRecord
attr_accessor :name, :active
end
user = User.new.tap do |u|
u.name = 'Guilherme'
u.active = true
end
user.respond_to? :active?
# => true
class CustomRecord
def method_missing(name, *args, &block)
name.to_s.end_with?('?') || super
self.class.send :define_method, name do
!!instance_variable_get("@#{name}".gsub /?$/, '')
end
send(name)
end
def respond_to_missing?(name, include_all)
name.to_s.end_with?('?') || super
end
end
user = User.new.tap { |u| u.name = 'Guilherme'; u.active = true }
class CustomRecord
def method_missing(name, *args, &block)
'TDC' * 1_000_000 # complex stuff
name.to_s.end_with?('?') || super
self.class.send :define_method, name do
!!instance_variable_get("@#{name}".gsub /?$/, '')
end
send(name)
end
def respond_to_missing?(name, include_all)
name.to_s.end_with?('?') || super
end
end
user = User.new.tap { |u| u.name = 'Guilherme'; u.active = true }
puts Benchmark.measure { user.active? }
# => 0.000000 0.000000 0.000000 ( 0.001539)
puts Benchmark.measure { user.active? }
# => 0.000000 0.000000 0.000000 ( 0.000021)
TDC 2015 - Metaprogramação na prática
class User
def initialize(friends)
@friends = friends
end
end
guilherme = User.new [
'Danilo', 'Eder', 'Luan', 'Paulo', 'Sabrina', 'Tiago'
]
guilherme.number_of_friends
# => 6
TDC 2015 - Metaprogramação na prática
attr_*
class User
attr_accessor :name, :active
end
user = User.new.tap do |u|
u.name = 'Guilherme'
u.active = true
end
user.name
# => "Guilherme"
static VALUE
rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
{
int i;
for (i=0; i<argc; i++) {
rb_attr(klass, rb_to_id(argv[i]), TRUE, TRUE, TRUE);
}
return Qnil;
}
void
rb_attr(VALUE klass, ID id, int read, int write, int ex)
{
// (...) algumas coisas
if (read) {
rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv…
}
if (write) {
rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET…
}
}
Qual é o melhor?
Qual é o melhor?
eval, method_missing, define_method
http://tenderlovemaking.com/2013/03/03/dynamic_method_definitions.html
#send
def search_articles_by_user(user)
if logged_user.admin?
Article.admin_scope.search_by(user)
elsif logged_user.customer_admin?
Article.customer_admin_scope.search_by(user)
elsif logged_user.customer?
Article.customer_scope.search_by(user)
elsif logged_user.user?
Article.user_scope.search_by(user)
end
end
def search_articles_by_user(user)
user_levels = [:admin, :customer_admin, :customer, :user]
user_levels.each do |level|
if logged_user.send "#{level}?"
Article.send("#{level}_scope").search_by(user)
end
end
end
TDC 2015 - Metaprogramação na prática
Hooks
Hooks
included, extended, prepended, inherited
class User
include ImageTrick
attr_accessor :name, :image
has_attached_file :image
end
user = User.new.tap { |u| u.image = '123456.png' }
user.image_url
# => "https://imagetrick.com/123456.png"
module ImageTrick
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def has_attached_file(name)
define_method "#{name}_url" do
image_name = instance_variable_get("@#{name}")
"https://imagetrick.com/#{image_name}"
end
end
end
end
class User
include ImageTrick
attr_accessor :name, :image
has_attached_file :image
end
user = User.new.tap { |u| u.image = '123456.png' }
user.image_url
# => "https://imagetrick.com/123456.png"
Monkey Patch
(Open classes)
module ImageTrick
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def has_attached_file(name)
define_method "#{name}_url" do
image_name = instance_variable_get("@#{name}")
"https://imagetrick.com/#{image_name}"
end
end
end
end
class User
include ImageTrick
attr_accessor :name, :image
has_attached_file :image
end
user = User.new.tap { |u| u.image = '123456.png' }
user.image_url
# => "https://imagetrick.com/123456.png"
module ImageTrick
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def has_attached_file(name)
define_method "#{name}_url" do
image_name = instance_variable_get("@#{name}")
"https://imagetrick.com/#{image_name}"
end
end
end
end
module ImageTrick
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def has_attached_file(name)
define_method "#{name}_url" do
image_name = instance_variable_get("@#{name}")
"https://imagetrick.com/#{image_name}"
end
end
end
end
class String
def serialized
self.gsub(/[^a-zA-Z0-9.:/-_]+/, '-').downcase
end
end
module ImageTrick
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def has_attached_file(name)
define_method "#{name}_url" do
image_name = instance_variable_get("@#{name}")
"https://imagetrick.com/#{image_name}".serialized
end
end
end
end
class String
def serialized
self.gsub(/[^a-zA-Z0-9.:/-_]+/, '-').downcase
end
end
module ImageTrick
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def has_attached_file(name)
define_method "#{name}_url" do
image_name = instance_variable_get("@#{name}")
"https://imagetrick.com/#{image_name}".serialized
end
end
end
end
"Some string".serialized
# => "some-string"
module ImageTrick
module RefinedString
refine String do
def serialized
self.gsub(/[^a-zA-Z0-9.:/-_]+/, '-').downcase
end
end
end
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
using RefinedString
def has_attached_file(name)
define_method "#{name}_url" do
image_name = instance_variable_get("@#{name}")
"https://imagetrick.com/#{image_name}".serialized
end
end
end
end
"Some string".serialized
# => undefined method `serialized' for "Some string” (NoMethodError)
TDC 2015 - Metaprogramação na prática
…
TDC 2015 - Metaprogramação na prática
Obrigado.
Guilherme Carreiro
GitHub: @karreiro, Twitter: @g_carreiro

More Related Content

What's hot

JavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UXJavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UX
JWORKS powered by Ordina
 
Oop php 5
Oop php 5Oop php 5
Oop php 5
phpubl
 
Javascript
JavascriptJavascript
Javascript
theacadian
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
Iban Martinez
 
Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4
Javier Eguiluz
 
Beginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScriptBeginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScript
Stoyan Stefanov
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Libraries
jeresig
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection Smells
Matthias Noback
 
Zend framework 04 - forms
Zend framework 04 - formsZend framework 04 - forms
Zend framework 04 - forms
Tricode (part of Dept)
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
KyeongMook "Kay" Cha
 
Factory Girl
Factory GirlFactory Girl
Factory Girl
Gabe Evans
 
Data::FormValidator Simplified
Data::FormValidator SimplifiedData::FormValidator Simplified
Data::FormValidator Simplified
Fred Moyer
 
Patterns in PHP
Patterns in PHPPatterns in PHP
Patterns in PHP
Diego Lewin
 
Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014
Jaroslaw Palka
 
Mp24: The Bachelor, a facebook game
Mp24: The Bachelor, a facebook gameMp24: The Bachelor, a facebook game
Mp24: The Bachelor, a facebook game
Montreal Python
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
Python Ireland
 
Drupal sins 2016 10-06
Drupal sins 2016 10-06Drupal sins 2016 10-06
Drupal sins 2016 10-06
Aaron Crosman
 
4. Метапрограмиране
4. Метапрограмиране4. Метапрограмиране
4. Метапрограмиране
Stefan Kanev
 

What's hot (18)

JavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UXJavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UX
 
Oop php 5
Oop php 5Oop php 5
Oop php 5
 
Javascript
JavascriptJavascript
Javascript
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4
 
Beginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScriptBeginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScript
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Libraries
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection Smells
 
Zend framework 04 - forms
Zend framework 04 - formsZend framework 04 - forms
Zend framework 04 - forms
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
 
Factory Girl
Factory GirlFactory Girl
Factory Girl
 
Data::FormValidator Simplified
Data::FormValidator SimplifiedData::FormValidator Simplified
Data::FormValidator Simplified
 
Patterns in PHP
Patterns in PHPPatterns in PHP
Patterns in PHP
 
Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014
 
Mp24: The Bachelor, a facebook game
Mp24: The Bachelor, a facebook gameMp24: The Bachelor, a facebook game
Mp24: The Bachelor, a facebook game
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
 
Drupal sins 2016 10-06
Drupal sins 2016 10-06Drupal sins 2016 10-06
Drupal sins 2016 10-06
 
4. Метапрограмиране
4. Метапрограмиране4. Метапрограмиране
4. Метапрограмиране
 

Similar to TDC 2015 - Metaprogramação na prática

TDC 2015 - DSLs em Ruby
TDC 2015 - DSLs em RubyTDC 2015 - DSLs em Ruby
TDC 2015 - DSLs em Ruby
Guilherme Carreiro
 
WordPress Capabilities Magic
WordPress Capabilities MagicWordPress Capabilities Magic
WordPress Capabilities Magic
mannieschumpert
 
Implementation of EAV pattern for ActiveRecord models
Implementation of EAV pattern for ActiveRecord modelsImplementation of EAV pattern for ActiveRecord models
Implementation of EAV pattern for ActiveRecord models
Kostyantyn Stepanyuk
 
Ruby on rails
Ruby on rails Ruby on rails
Ruby on rails
Mohit Jain
 
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
Barang CK
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP plugins
Pierre MARTIN
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
Ryunosuke SATO
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
Abbas Ali
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
NSCoder Mexico
 
Using Actions and Filters in WordPress to Make a Plugin Your Own
Using Actions and Filters in WordPress to Make a Plugin Your OwnUsing Actions and Filters in WordPress to Make a Plugin Your Own
Using Actions and Filters in WordPress to Make a Plugin Your Own
Brian Hogg
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
Rebecca Murphey
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
ShriKant Vashishtha
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
Pamela Fox
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
Javier Eguiluz
 
Let's write secure Drupal code! - DrupalCamp London 2019
Let's write secure Drupal code! - DrupalCamp London 2019Let's write secure Drupal code! - DrupalCamp London 2019
Let's write secure Drupal code! - DrupalCamp London 2019
Balázs Tatár
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and Lodash
Bret Little
 
WordPress Theme Design and Development Workshop - Day 3
WordPress Theme Design and Development Workshop - Day 3WordPress Theme Design and Development Workshop - Day 3
WordPress Theme Design and Development Workshop - Day 3
Mizanur Rahaman Mizan
 

Similar to TDC 2015 - Metaprogramação na prática (20)

TDC 2015 - DSLs em Ruby
TDC 2015 - DSLs em RubyTDC 2015 - DSLs em Ruby
TDC 2015 - DSLs em Ruby
 
WordPress Capabilities Magic
WordPress Capabilities MagicWordPress Capabilities Magic
WordPress Capabilities Magic
 
Implementation of EAV pattern for ActiveRecord models
Implementation of EAV pattern for ActiveRecord modelsImplementation of EAV pattern for ActiveRecord models
Implementation of EAV pattern for ActiveRecord models
 
Ruby on rails
Ruby on rails Ruby on rails
Ruby on rails
 
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP plugins
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
 
Using Actions and Filters in WordPress to Make a Plugin Your Own
Using Actions and Filters in WordPress to Make a Plugin Your OwnUsing Actions and Filters in WordPress to Make a Plugin Your Own
Using Actions and Filters in WordPress to Make a Plugin Your Own
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
 
Let's write secure Drupal code! - DrupalCamp London 2019
Let's write secure Drupal code! - DrupalCamp London 2019Let's write secure Drupal code! - DrupalCamp London 2019
Let's write secure Drupal code! - DrupalCamp London 2019
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and Lodash
 
WordPress Theme Design and Development Workshop - Day 3
WordPress Theme Design and Development Workshop - Day 3WordPress Theme Design and Development Workshop - Day 3
WordPress Theme Design and Development Workshop - Day 3
 

Recently uploaded

Pigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending PlantPigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending Plant
LINUS PROJECTS (INDIA)
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
aakash malhotra
 
Calgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptxCalgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptx
ishalveerrandhawa1
 
The Role of Technology in Payroll Statutory Compliance (1).pdf
The Role of Technology in Payroll Statutory Compliance (1).pdfThe Role of Technology in Payroll Statutory Compliance (1).pdf
The Role of Technology in Payroll Statutory Compliance (1).pdf
paysquare consultancy
 
The Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF GuideThe Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF Guide
Shiv Technolabs
 
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAIApplying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
ssuserd4e0d2
 
Implementations of Fused Deposition Modeling in real world
Implementations of Fused Deposition Modeling  in real worldImplementations of Fused Deposition Modeling  in real world
Implementations of Fused Deposition Modeling in real world
Emerging Tech
 
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
Edge AI and Vision Alliance
 
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck
Lidia A.
 
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
bhumivarma35300
 
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
aslasdfmkhan4750
 
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Muhammad Ali
 
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
Priyanka Aash
 
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence
rajancomputerfbd
 
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and OllamaTirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Zilliz
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
Zilliz
 
The Evolution of Remote Server Management
The Evolution of Remote Server ManagementThe Evolution of Remote Server Management
The Evolution of Remote Server Management
Bert Blevins
 
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdfAcumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
BrainSell Technologies
 
Comparison Table of DiskWarrior Alternatives.pdf
Comparison Table of DiskWarrior Alternatives.pdfComparison Table of DiskWarrior Alternatives.pdf
Comparison Table of DiskWarrior Alternatives.pdf
Andrey Yasko
 
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSECHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
kumarjarun2010
 

Recently uploaded (20)

Pigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending PlantPigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending Plant
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
 
Calgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptxCalgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptx
 
The Role of Technology in Payroll Statutory Compliance (1).pdf
The Role of Technology in Payroll Statutory Compliance (1).pdfThe Role of Technology in Payroll Statutory Compliance (1).pdf
The Role of Technology in Payroll Statutory Compliance (1).pdf
 
The Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF GuideThe Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF Guide
 
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAIApplying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
 
Implementations of Fused Deposition Modeling in real world
Implementations of Fused Deposition Modeling  in real worldImplementations of Fused Deposition Modeling  in real world
Implementations of Fused Deposition Modeling in real world
 
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
 
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck
 
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
 
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
High Profile Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class ...
 
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
Litestack talk at Brighton 2024 (Unleashing the power of SQLite for Ruby apps)
 
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
(CISOPlatform Summit & SACON 2024) Keynote _ Power Digital Identities With AI...
 
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence
 
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and OllamaTirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
 
The Evolution of Remote Server Management
The Evolution of Remote Server ManagementThe Evolution of Remote Server Management
The Evolution of Remote Server Management
 
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdfAcumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
 
Comparison Table of DiskWarrior Alternatives.pdf
Comparison Table of DiskWarrior Alternatives.pdfComparison Table of DiskWarrior Alternatives.pdf
Comparison Table of DiskWarrior Alternatives.pdf
 
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSECHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
 

TDC 2015 - Metaprogramação na prática

  • 2. Guilherme Carreiro Campinas, SP Ruby, JavaScript, Java dextra/projects karreiro/picuture_from discourse/OneBox
  • 4. Guilherme Carreiro Campinas, SP Ruby, JavaScript, Java dextra/projects karreiro/picuture_from discourse/OneBox
  • 7. class User < ActiveRecord::Base # empty end user = User.new(name: 'Guilherme', active: true) user.active? # => true
  • 9. Metaprogramming is writing code that manipulates code at runtime.
  • 10. class User < ActiveRecord::Base # empty end user = User.new(name: 'Guilherme', active: true) user.active? # => true
  • 11. class User attr_accessor :name, :active end user = User.new.tap do |u| u.name = 'Guilherme' u.active = true end user.active? # => NoMethodError: undefined method `active?' for #<User:0x007fe5d189a2b0 @name="Guilherme", @active=true>
  • 13. #eval
  • 14. class User def self.define_methods attributes = [:name?, :active?] attributes.each do |attribute| class_eval <<-EOMETHOD def #{attribute} true end EOMETHOD end end end user = User.new user.name? # => NoMethodError: undefined method `name?’ for #<User:0x007f...> User.define_methods user.name? # => true
  • 15. class User class_eval do def self.class_name '~ User ~' end end end User.class_name # => "~ User ~” user = User.new user.instance_eval do def self.instance_name '~ user ~' end end user.instance_name # => "~ user ~” class_eval vs. instance_eval
  • 18. class User < ActiveRecord::Base enum status: { active: 0, archived: 1 } end user = User.new user.status # => 'archived' user.active? # => false user.active! # => true user.active? # => true
  • 19. module ActiveRecord module Enum # (...) # Dado que value: 'active', name: 'status' e i: 0 # def active?() status == 0 end define_method("#{value}?") { self[name] == i } # def active!() update! status: :active end define_method("#{value}!") { update! name => value } # (...) end end
  • 20. class User attr_accessor :name, :status def active? self.status == 'active' end def archived? self.status == 'archived' end def deleted? self.status == 'deleted' end end User.new.tap { |u| u.status = 'active' }.active? # => true User.new.tap { |u| u.status = 'active' }.archived? # => false User.new.tap { |u| u.status = 'active' }.deleted? # => false
  • 21. class User attr_accessor :name, :status STATUSES = [:active, :archived, :deleted] STATUSES.each do |status| define_method "#{status}?" do self.status == status.to_s end end end User.new.tap { |u| u.status = 'active' }.active? # => true User.new.tap { |u| u.status = 'active' }.archived? # => false User.new.tap { |u| u.status = 'active' }.deleted? # => false
  • 23. class User attr_accessor :name, :active end user = User.new.tap do |u| u.name = 'Guilherme' u.active = true end
  • 24. class CustomRecord def method_missing(name, *args, &block) name.to_s.end_with?('?') || super !!instance_variable_get("@#{name}".gsub /?$/, '') end end class User < CustomRecord attr_accessor :name, :active end user = User.new.tap do |u| u.name = 'Guilherme' u.active = true end user.active? # => true
  • 25. class CustomRecord def method_missing(name, *args, &block) name.to_s.end_with?('?') || super !!instance_variable_get("@#{name}".gsub /?$/, '') end end class User < CustomRecord attr_accessor :name, :active end user = User.new.tap do |u| u.name = 'Guilherme' u.active = true end user.active? # => true user.respond_to? :active? # => false
  • 26. class CustomRecord def method_missing(name, *args, &block) name.to_s.end_with?('?') || super !!instance_variable_get("@#{name}".gsub /?$/, '') end def respond_to_missing?(name, include_all) name.to_s.end_with?('?') || super end end class User < CustomRecord attr_accessor :name, :active end user = User.new.tap do |u| u.name = 'Guilherme' u.active = true end user.respond_to? :active? # => true
  • 27. class CustomRecord def method_missing(name, *args, &block) name.to_s.end_with?('?') || super self.class.send :define_method, name do !!instance_variable_get("@#{name}".gsub /?$/, '') end send(name) end def respond_to_missing?(name, include_all) name.to_s.end_with?('?') || super end end user = User.new.tap { |u| u.name = 'Guilherme'; u.active = true }
  • 28. class CustomRecord def method_missing(name, *args, &block) 'TDC' * 1_000_000 # complex stuff name.to_s.end_with?('?') || super self.class.send :define_method, name do !!instance_variable_get("@#{name}".gsub /?$/, '') end send(name) end def respond_to_missing?(name, include_all) name.to_s.end_with?('?') || super end end user = User.new.tap { |u| u.name = 'Guilherme'; u.active = true } puts Benchmark.measure { user.active? } # => 0.000000 0.000000 0.000000 ( 0.001539) puts Benchmark.measure { user.active? } # => 0.000000 0.000000 0.000000 ( 0.000021)
  • 30. class User def initialize(friends) @friends = friends end end guilherme = User.new [ 'Danilo', 'Eder', 'Luan', 'Paulo', 'Sabrina', 'Tiago' ] guilherme.number_of_friends # => 6
  • 33. class User attr_accessor :name, :active end user = User.new.tap do |u| u.name = 'Guilherme' u.active = true end user.name # => "Guilherme"
  • 34. static VALUE rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass) { int i; for (i=0; i<argc; i++) { rb_attr(klass, rb_to_id(argv[i]), TRUE, TRUE, TRUE); } return Qnil; } void rb_attr(VALUE klass, ID id, int read, int write, int ex) { // (...) algumas coisas if (read) { rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv… } if (write) { rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET… } }
  • 35. Qual é o melhor?
  • 36. Qual é o melhor? eval, method_missing, define_method http://tenderlovemaking.com/2013/03/03/dynamic_method_definitions.html
  • 37. #send
  • 38. def search_articles_by_user(user) if logged_user.admin? Article.admin_scope.search_by(user) elsif logged_user.customer_admin? Article.customer_admin_scope.search_by(user) elsif logged_user.customer? Article.customer_scope.search_by(user) elsif logged_user.user? Article.user_scope.search_by(user) end end
  • 39. def search_articles_by_user(user) user_levels = [:admin, :customer_admin, :customer, :user] user_levels.each do |level| if logged_user.send "#{level}?" Article.send("#{level}_scope").search_by(user) end end end
  • 41. Hooks
  • 43. class User include ImageTrick attr_accessor :name, :image has_attached_file :image end user = User.new.tap { |u| u.image = '123456.png' } user.image_url # => "https://imagetrick.com/123456.png"
  • 44. module ImageTrick def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def has_attached_file(name) define_method "#{name}_url" do image_name = instance_variable_get("@#{name}") "https://imagetrick.com/#{image_name}" end end end end class User include ImageTrick attr_accessor :name, :image has_attached_file :image end user = User.new.tap { |u| u.image = '123456.png' } user.image_url # => "https://imagetrick.com/123456.png"
  • 46. module ImageTrick def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def has_attached_file(name) define_method "#{name}_url" do image_name = instance_variable_get("@#{name}") "https://imagetrick.com/#{image_name}" end end end end class User include ImageTrick attr_accessor :name, :image has_attached_file :image end user = User.new.tap { |u| u.image = '123456.png' } user.image_url # => "https://imagetrick.com/123456.png"
  • 47. module ImageTrick def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def has_attached_file(name) define_method "#{name}_url" do image_name = instance_variable_get("@#{name}") "https://imagetrick.com/#{image_name}" end end end end
  • 48. module ImageTrick def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def has_attached_file(name) define_method "#{name}_url" do image_name = instance_variable_get("@#{name}") "https://imagetrick.com/#{image_name}" end end end end
  • 49. class String def serialized self.gsub(/[^a-zA-Z0-9.:/-_]+/, '-').downcase end end module ImageTrick def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def has_attached_file(name) define_method "#{name}_url" do image_name = instance_variable_get("@#{name}") "https://imagetrick.com/#{image_name}".serialized end end end end
  • 50. class String def serialized self.gsub(/[^a-zA-Z0-9.:/-_]+/, '-').downcase end end module ImageTrick def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def has_attached_file(name) define_method "#{name}_url" do image_name = instance_variable_get("@#{name}") "https://imagetrick.com/#{image_name}".serialized end end end end "Some string".serialized # => "some-string"
  • 51. module ImageTrick module RefinedString refine String do def serialized self.gsub(/[^a-zA-Z0-9.:/-_]+/, '-').downcase end end end def self.included(klass) klass.extend(ClassMethods) end module ClassMethods using RefinedString def has_attached_file(name) define_method "#{name}_url" do image_name = instance_variable_get("@#{name}") "https://imagetrick.com/#{image_name}".serialized end end end end "Some string".serialized # => undefined method `serialized' for "Some string” (NoMethodError)
  • 53.