This document discusses metaprogramming in Ruby. It begins with an introduction to metaprogramming as writing programs that write programs, rather than code generation. It then discusses why metaprogramming is commonly used in Ruby through examples like attr_accessor. It notes some drawbacks like writing difficult to understand code. It covers topics like method dispatch, Ruby classes, eval, instance_eval, class_eval, and scoping.
This presentation is an introduction to Ruby eval. It also talks about instance_eval and class_eval methods and lists a meta programming example using eval at the end of the presentation.
Functional programming in Scala. Looking at various examples of defining a program first and executing it at some later stage, separating pure functions from side effects.
This presentation is an introduction to Ruby eval. It also talks about instance_eval and class_eval methods and lists a meta programming example using eval at the end of the presentation.
Functional programming in Scala. Looking at various examples of defining a program first and executing it at some later stage, separating pure functions from side effects.
The great attractiveness of purely functional languages is their ability to depart from sequential order of computation. Theoretically, it enables two important features of the compiler:
1) The ability to reorder computation flow, making the program implicitly parallelisable. Modern imperative language compilers, even using careful synchronization of concurrent code, still generate huge chunks of sequential instructions that need to be executed on a single processor core; a purely functional language compilers can dispatch very small chunks to many (hundreds and thousands) of cores, carefully eliminating as many execution path dependencies as possible.
2) As the compiler formalizes different types of side effects, it can detect a whole new class of program errors at compile time, including resource acquisition and releasing problems, concurrent access to shared resources, many types of deadlocks etc. It is not yet a full-fledged program verification, but it is a big step in that direction.
Scala is a semi-imperative language with strong support for functional programming and rich type system. One can isolate the purely functional core of the language which can be put on the firm mathematical foundation of dependent type theories. We argue that it is possible to treat Scala code as it's written by now as an implicit do-notation which can be then reduced to a purely functional core by means of recently introduced Scala macros. The formalism of arrows and applicative contexts can bring Scala to a full glory of an implicitly parallelisable programming language, while still keeping its syntax mostly unchanged.
This ppt gives information about:
1. OOPs Theory
2. Defining a Class
3. Creating an Object
4. The $this Attribute
5. Creating Constructors
6. Creating Destructors
JavaScript is scripting/programming language. File Extension of JavaScript is ".js”. This extension can be catched by a number of applications including Windows Script Host, Dreamweaver MX, Notepad, Netscape Navigator, PavScrip, UltraEdit.
Swift is the latest new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility. This presentation is all about Closures, Structures, Enum, Memory Management & Extensions.
The great attractiveness of purely functional languages is their ability to depart from sequential order of computation. Theoretically, it enables two important features of the compiler:
1) The ability to reorder computation flow, making the program implicitly parallelisable. Modern imperative language compilers, even using careful synchronization of concurrent code, still generate huge chunks of sequential instructions that need to be executed on a single processor core; a purely functional language compilers can dispatch very small chunks to many (hundreds and thousands) of cores, carefully eliminating as many execution path dependencies as possible.
2) As the compiler formalizes different types of side effects, it can detect a whole new class of program errors at compile time, including resource acquisition and releasing problems, concurrent access to shared resources, many types of deadlocks etc. It is not yet a full-fledged program verification, but it is a big step in that direction.
Scala is a semi-imperative language with strong support for functional programming and rich type system. One can isolate the purely functional core of the language which can be put on the firm mathematical foundation of dependent type theories. We argue that it is possible to treat Scala code as it's written by now as an implicit do-notation which can be then reduced to a purely functional core by means of recently introduced Scala macros. The formalism of arrows and applicative contexts can bring Scala to a full glory of an implicitly parallelisable programming language, while still keeping its syntax mostly unchanged.
This ppt gives information about:
1. OOPs Theory
2. Defining a Class
3. Creating an Object
4. The $this Attribute
5. Creating Constructors
6. Creating Destructors
JavaScript is scripting/programming language. File Extension of JavaScript is ".js”. This extension can be catched by a number of applications including Windows Script Host, Dreamweaver MX, Notepad, Netscape Navigator, PavScrip, UltraEdit.
Swift is the latest new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility. This presentation is all about Closures, Structures, Enum, Memory Management & Extensions.
(RubyFools 2008)
"Plugins are more than just shiny nuggets of code which rain down from the higher echelons of the Rails pantheon; they are loyal and useful servants that anyone can employ to help reuse code between applications. Without a little guidance, however, the process of figuring out just how to tame these beasts can be overwhelming.
"This presentation will help give developers the boost that's often required to get up to speed developing plugins. We'll cover the hooks that Rails' plugin mechanism makes available, and how to put them to best use in practice.
"Once we've covered the groundwork, we'll start to look at more advanced programming techniques for sharing code (and other files) between Rails applications. With a few key programming techniques under our belt, we can use plugins to alter and enhance the Rails framework itself, and become masters of Ruby's object model along the way."
You've learned to program in Ruby, but now you want to start learning about how to move beyond the language basics and make use of some of the dynamic parts of the Ruby language. We'll cover that a bit here.
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesTchelinux
Sobre o palestrante: Formado na UFPel no início do ano corrente, trabalhou com desenvolvimento de hardware para TV digital durante a graduação. Entretanto, sempre foi apaixonado por belas linguagens de programação, e destas, Ruby é a que mais se destaca. Atualmente aguarda o mês de junho, quando começa a trabalhar na ThoughtWorks, em Porto Alegre.
Discussing language constructs with fellow developers in the context of solving a particular problem is something we do routinely. While most such conversations are productive and useful, a fair portion degenerate into angry brawls. A pattern we've observed in the latter situation is that a surprising number of times the argument is that "Why shouldn't I use language feature X to achieve objective Y- after all, the language supports X."
In this talk Aakash and Niranjan walk through a few features of the Ruby language which when used wisely allows programmers to solve problems elegantly but if they are used without caution can lead to bad code.
State of ICS and IoT Cyber Threat Landscape Report 2024 previewPrayukth K V
The IoT and OT threat landscape report has been prepared by the Threat Research Team at Sectrio using data from Sectrio, cyber threat intelligence farming facilities spread across over 85 cities around the world. In addition, Sectrio also runs AI-based advanced threat and payload engagement facilities that serve as sinks to attract and engage sophisticated threat actors, and newer malware including new variants and latent threats that are at an earlier stage of development.
The latest edition of the OT/ICS and IoT security Threat Landscape Report 2024 also covers:
State of global ICS asset and network exposure
Sectoral targets and attacks as well as the cost of ransom
Global APT activity, AI usage, actor and tactic profiles, and implications
Rise in volumes of AI-powered cyberattacks
Major cyber events in 2024
Malware and malicious payload trends
Cyberattack types and targets
Vulnerability exploit attempts on CVEs
Attacks on counties – USA
Expansion of bot farms – how, where, and why
In-depth analysis of the cyber threat landscape across North America, South America, Europe, APAC, and the Middle East
Why are attacks on smart factories rising?
Cyber risk predictions
Axis of attacks – Europe
Systemic attacks in the Middle East
Download the full report from here:
https://sectrio.com/resources/ot-threat-landscape-reports/sectrio-releases-ot-ics-and-iot-security-threat-landscape-report-2024/
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...James Anderson
Effective Application Security in Software Delivery lifecycle using Deployment Firewall and DBOM
The modern software delivery process (or the CI/CD process) includes many tools, distributed teams, open-source code, and cloud platforms. Constant focus on speed to release software to market, along with the traditional slow and manual security checks has caused gaps in continuous security as an important piece in the software supply chain. Today organizations feel more susceptible to external and internal cyber threats due to the vast attack surface in their applications supply chain and the lack of end-to-end governance and risk management.
The software team must secure its software delivery process to avoid vulnerability and security breaches. This needs to be achieved with existing tool chains and without extensive rework of the delivery processes. This talk will present strategies and techniques for providing visibility into the true risk of the existing vulnerabilities, preventing the introduction of security issues in the software, resolving vulnerabilities in production environments quickly, and capturing the deployment bill of materials (DBOM).
Speakers:
Bob Boule
Robert Boule is a technology enthusiast with PASSION for technology and making things work along with a knack for helping others understand how things work. He comes with around 20 years of solution engineering experience in application security, software continuous delivery, and SaaS platforms. He is known for his dynamic presentations in CI/CD and application security integrated in software delivery lifecycle.
Gopinath Rebala
Gopinath Rebala is the CTO of OpsMx, where he has overall responsibility for the machine learning and data processing architectures for Secure Software Delivery. Gopi also has a strong connection with our customers, leading design and architecture for strategic implementations. Gopi is a frequent speaker and well-known leader in continuous delivery and integrating security into software delivery.
Securing your Kubernetes cluster_ a step-by-step guide to success !KatiaHIMEUR1
Today, after several years of existence, an extremely active community and an ultra-dynamic ecosystem, Kubernetes has established itself as the de facto standard in container orchestration. Thanks to a wide range of managed services, it has never been so easy to set up a ready-to-use Kubernetes cluster.
However, this ease of use means that the subject of security in Kubernetes is often left for later, or even neglected. This exposes companies to significant risks.
In this talk, I'll show you step-by-step how to secure your Kubernetes cluster for greater peace of mind and reliability.
GridMate - End to end testing is a critical piece to ensure quality and avoid...ThomasParaiso2
End to end testing is a critical piece to ensure quality and avoid regressions. In this session, we share our journey building an E2E testing pipeline for GridMate components (LWC and Aura) using Cypress, JSForce, FakerJS…
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionAggregage
Join Maher Hanafi, VP of Engineering at Betterworks, in this new session where he'll share a practical framework to transform Gen AI prototypes into impactful products! He'll delve into the complexities of data collection and management, model selection and optimization, and ensuring security, scalability, and responsible use.
In his public lecture, Christian Timmerer provides insights into the fascinating history of video streaming, starting from its humble beginnings before YouTube to the groundbreaking technologies that now dominate platforms like Netflix and ORF ON. Timmerer also presents provocative contributions of his own that have significantly influenced the industry. He concludes by looking at future challenges and invites the audience to join in a discussion.
Climate Impact of Software Testing at Nordic Testing DaysKari Kakkonen
My slides at Nordic Testing Days 6.6.2024
Climate impact / sustainability of software testing discussed on the talk. ICT and testing must carry their part of global responsibility to help with the climat warming. We can minimize the carbon footprint but we can also have a carbon handprint, a positive impact on the climate. Quality characteristics can be added with sustainability, and then measured continuously. Test environments can be used less, and in smaller scale and on demand. Test techniques can be used in optimizing or minimizing number of tests. Test automation can be used to speed up testing.
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...SOFTTECHHUB
The choice of an operating system plays a pivotal role in shaping our computing experience. For decades, Microsoft's Windows has dominated the market, offering a familiar and widely adopted platform for personal and professional use. However, as technological advancements continue to push the boundaries of innovation, alternative operating systems have emerged, challenging the status quo and offering users a fresh perspective on computing.
One such alternative that has garnered significant attention and acclaim is Nitrux Linux 3.5.0, a sleek, powerful, and user-friendly Linux distribution that promises to redefine the way we interact with our devices. With its focus on performance, security, and customization, Nitrux Linux presents a compelling case for those seeking to break free from the constraints of proprietary software and embrace the freedom and flexibility of open-source computing.
Communications Mining Series - Zero to Hero - Session 1DianaGray10
This session provides introduction to UiPath Communication Mining, importance and platform overview. You will acquire a good understand of the phases in Communication Mining as we go over the platform with you. Topics covered:
• Communication Mining Overview
• Why is it important?
• How can it help today’s business and the benefits
• Phases in Communication Mining
• Demo on Platform overview
• Q/A
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfPeter Spielvogel
Building better applications for business users with SAP Fiori.
• What is SAP Fiori and why it matters to you
• How a better user experience drives measurable business benefits
• How to get started with SAP Fiori today
• How SAP Fiori elements accelerates application development
• How SAP Build Code includes SAP Fiori tools and other generative artificial intelligence capabilities
• How SAP Fiori paves the way for using AI in SAP apps
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf91mobiles
91mobiles recently conducted a Smart TV Buyer Insights Survey in which we asked over 3,000 respondents about the TV they own, aspects they look at on a new TV, and their TV buying preferences.
Sudheer Mechineni, Head of Application Frameworks, Standard Chartered Bank
Discover how Standard Chartered Bank harnessed the power of Neo4j to transform complex data access challenges into a dynamic, scalable graph database solution. This keynote will cover their journey from initial adoption to deploying a fully automated, enterprise-grade causal cluster, highlighting key strategies for modelling organisational changes and ensuring robust disaster recovery. Learn how these innovations have not only enhanced Standard Chartered Bank’s data infrastructure but also positioned them as pioneers in the banking sector’s adoption of graph technology.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
10. Why?
We all do it.
Ruby attr_accessor :my_attribute
11. Why?
We all do it.
Ruby attr_accessor :my_attribute
def my_attribute
@my_attribute
end
def my_attribute=(my_attribute)
@my_attribute = my_attribute
end
12. Why?
We all do it.
Ruby attr_accessor :my_attribute
Java public int getAttribute() {
return attribute;
}
public void setAttribute(int newAttribute) {
attribute = newAttribute;
}
13. Why?
We all do it.
ner
in Ruby
W attr_accessor :my_attribute
Java public int getAttribute() {
return attribute;
}
public void setAttribute(int newAttribute) {
attribute = newAttribute;
}
14. Why?
def age
@age || 'not set'
end
def gender
@gender || 'not set'
end
def name
@name || 'not set'
end
15. Why?
def age
@age || 'not set'
end
def gender
@gender || 'not set'
end
def name
@name || 'not set'
end
[:age, :gender, :name].each do |attr|
define_method(attr) do
instance_variable_get(:"@#{attr}") || 'not set'
end
end
54. eval, instance_eval,
class_eval
class Module
def create_attr(attribute)
class_eval("def #{attribute}; @#{attribute}; end")
end
end
55. eval, instance_eval,
class_eval
class Module
def create_attr(attribute)
class_eval("def #{attribute}; @#{attribute}; end")
end
end
class M
create_attr :hi
end
56. eval, instance_eval,
class_eval
class Module
def create_attr(attribute)
class_eval("def #{attribute}; @#{attribute}; end")
end
end
def M
class M def hi
create_attr :hi @hi
end end
end
58. Defining methods
For an object
o = Object.new
o.instance_eval("def just_this_object; end")
o.just_this_object
59. Defining methods
For an object
o = Object.new
o.instance_eval("def just_this_object; end")
o.just_this_object
Object.new.just_this_object
# NoMethodError: undefined method `just_this_object'
60. Defining methods
For an object
o = Object.new
o.instance_eval("def just_this_object; end")
o.just_this_object
Object.new.just_this_object
# NoMethodError: undefined method `just_this_object'
o = Object.new
o.instance_eval {
def just_this_object
end
}
61. Defining methods
For an object
o = Object.new
o.extend(Module.new {
def just_this_object
end
})
62. Defining methods
For a class
MyClass = Class.new
class MyClass
def new_method
end
end
MyClass.new.respond_to?(:new_method) # true
63. Defining methods
For a class
MyClass = Class.new
MyClass.class_eval " MyClass.class_eval do
def new_method def new_method
end end
" end
MyClass.send(:define_method, :new_method) {
# your method body
}
69. Scoping
a = 'hello'
module Project
class Main
def run
puts a
end
end
end
Project::Main.new.run
# undefined local variable or method `a' for #<Project::Main> (NameError)
70. Scoping
module Project
class Main
end
end
a = 'hello'
Project::Main.class_eval do
define_method(:run) do
puts a
end
end
Project::Main.new.run # => hello
71. Scoping
Example: Connection Sharing
module AddConnections
def self.add_connection_methods(cls, host, port)
cls.class_eval do
define_method(:get_connection) do
puts "Getting connection for #{host}:#{port}"
end
define_method(:host) { host }
define_method(:port) { port }
end
end
end
72. Scoping
Example: Connection Sharing
module AddConnections
def self.add_connection_methods(cls, host, port)
cls.class_eval do
define_method(:get_connection) do
puts "Getting connection for #{host}:#{port}"
end
define_method(:host) { host }
define_method(:port) { port }
end
end
end
Client = Class.new
AddConnections.add_connection_methods(Client, 'localhost', 8080)
Client.new.get_connection # Getting connection for localhost:8080
Client.new.host # localhost
Client.new.port # 8080
74. Scoping
Kernel#binding
Let’s you leak the current “bindings”
def create_connection(bind)
eval '
connection = "I am a connection"
', bind
end
connection = nil
create_connection(binding)
connection # => I am a connection
75. Scoping
Kernel#binding
Let’s you leak the current “bindings”
def create_connection(bind)
eval '
connection = "I am a connection"
', bind
end
Calls connection = nil
with the create_connection(binding)
current connection # => I am a connection
state
76. Scoping
Kernel#binding
Let’s you leak the current “bindings”
def create_connection(bind)
eval '
connection = "I am a connection"
', bind
end
Calls connection = nil
with the create_connection(binding)
current connection # => I am a connection
state
MAGIC!
77. Scoping
Kernel#binding
Let’s you leak the current “bindings”
def create_connection(bind)
eval '
connection = "I am a connection"
', bind
end
# connection = nil
create_connection(binding)
connection
# undefined local variable or method `connection'
78. Scoping
Kernel#binding
Let’s you leak the current “bindings”
def create_connection(bind)
eval '
connection = "I am a connection"
', bind
end
# connection = nil
create_connection(binding)
connection
# undefined local variable or method `connection'
You can’t add to the local variables via binding
79. Scoping
Kernel#binding
Let’s you leak the current “bindings”
def create_connection(bind)
eval '
connection = "I am a connection"
', bind
end
eval "connection = nil"
create_connection(binding)
connection
# undefined local variable or method `connection'
You can’t add to the local variables via eval
81. Scoping
Kernel#binding
TOPLEVEL_BINDING
a = 'hello'
module Program
class Main
def run
puts eval("a", TOPLEVEL_BINDING)
end
end
end
Program::Main.new.run # => hello
92. Interception!
Object#respond_to?(sym)
Example: Timing
module MethodsWithTiming
alias_method :original_respond_to?, :respond_to?
def method_missing(m, *args, &blk)
if timed_method = m.to_s[/^(.*)_with_timing$/, 1] and original_respond_to?(timed_method)
respond = nil
measurement = Benchmark.measure {
respond = send(timed_method, *args, &blk)
}
puts "Method #{m} took #{measurement}"
respond
else
super
end
end
def respond_to?(sym)
(timed_method = sym.to_s[/^(.*)_with_timing$/, 1]) ?
original_respond_to?(timed_method.to_sym) :
original_respond_to?(sym)
end
end
93. Interception!
Object#respond_to?(sym)
Example: Timing
module MethodsWithTiming
ge ts
alias_method :original_respond_to?, :respond_to?
It
def method_missing(m, *args, &blk)
r!
if timed_method = m.to_s[/^(.*)_with_timing$/, 1] and original_respond_to?(timed_method)
te
respond = nil
et
measurement = Benchmark.measure {
b
respond = send(timed_method, *args, &blk)
}
puts "Method #{m} took #{measurement}"
respond
else
super
end
end
def respond_to?(sym)
(timed_method = sym.to_s[/^(.*)_with_timing$/, 1]) ?
original_respond_to?(timed_method.to_sym) :
original_respond_to?(sym)
end
end
94. Interception!
Object#respond_to_missing?(sym) (1.9 only)
Example: Timing
module MethodsWithTiming
def method_missing(m, *args, &blk)
if timed_method = m.to_s[/^(.*)_with_timing$/, 1] and respond_to?(timed_method)
respond = nil
measurement = Benchmark.measure {
respond = send(timed_method, *args, &blk)
}
puts "Method #{m} took #{measurement}"
respond
else
super
end
end
def respond_to_missing?(sym)
(timed_method = sym.to_s[/^(.*)_with_timing$/, 1]) ?
respond_to?(timed_method.to_sym) :
super
end
end
98. Interception!
Example: Loader
class Loader
def self.const_missing(sym)
file = File.join(File.dirname(__FILE__), "#{sym.to_s.downcase}.rb")
if File.exist?(file)
require file
Object.const_defined?(sym) ? Object.const_get(sym) : super
else
puts "can't find #{file}, sorry!"
super
end
end
end
99. Interception!
Example: Loader
class Loader
def self.const_missing(sym)
file = File.join(File.dirname(__FILE__), "#{sym.to_s.downcase}.rb")
if File.exist?(file)
require file
Object.const_defined?(sym) ? Object.const_get(sym) : super
else
puts "can't find #{file}, sorry!"
super
end
end
end
Loader::Auto
# can't find ./auto.rb, sorry!
# NameError: uninitialized constant Loader::Auto
# or, if you have an ./auto.rb
Loader::Auto
# => Auto
103. Callbacks
Module#method_added
class MyClass
def self.method_added(m)
puts "adding #{m}"
end
puts "defining my method"
def my_method
'two'
end
puts "done defining my method"
end
104. Callbacks
Module#method_added
class MyClass defining my method
def self.method_added(m) adding my_method
puts "adding #{m}" done defining my method
end
puts "defining my method"
def my_method
'two'
end
puts "done defining my method"
end
105. Callbacks
Module#method_added
Example: Thor!
class Tasks
def self.desc(desc)
@desc = desc
end
def self.method_added(m)
(@method_descs ||= {})[m] = @desc
@desc = nil
end
def self.method_description(m)
method_defined?(m) ?
@method_descs[m] || "This action isn't documented" :
"This action doesn't exist"
end
desc "Start server"
def start
end
def stop
end
end
106. Callbacks
Module#method_added
Example: Thor! Record the description
class Tasks
def self.desc(desc)
@desc = desc
When a method is added,
end record the description associated
def self.method_added(m) with that method
(@method_descs ||= {})[m] = @desc
@desc = nil
end Provide the description for a
def self.method_description(m)
method, or, if not found, some
method_defined?(m) ? default string.
@method_descs[m] || "This action isn't documented" :
"This action doesn't exist"
end
desc "Start server"
def start
end
def stop
end
end
107. Callbacks
Module#method_added
Example: Thor! Record the description
class Tasks
def self.desc(desc)
@desc = desc
When a method is added,
end record the description associated
def self.method_added(m) with that method
(@method_descs ||= {})[m] = @desc
@desc = nil
end Provide the description for a
def self.method_description(m)
method, or, if not found, some
method_defined?(m) ? default string.
@method_descs[m] || "This action isn't documented" :
"This action doesn't exist"
end
desc "Start server"
def start
end
Described!
def stop
end
end
108. Callbacks
Module#method_added
Example: Thor! Query your methods!
class Tasks puts Tasks.method_description(:start)
def self.desc(desc) # => Start server
@desc = desc puts Tasks.method_description(:stop)
end
# => This action isn't documented
def self.method_added(m) puts Tasks.method_description(:restart)
(@method_descs ||= {})[m] = @desc # => This action doesn't exist
@desc = nil
end
def self.method_description(m)
method_defined?(m) ?
@method_descs[m] || "This action isn't documented" :
"This action doesn't exist"
end
desc "Start server"
def start
end
def stop
end
end
113. Callbacks
Module#included
module Logger
def self.included(m)
puts "adding logging to #{m}"
end
end
class Server
include Logger
end
# adding logging to Server
114. Callbacks
Module#included
Example: ClassMethods pattern
module Logger class Server
def self.included(m) include Logger
puts "adding logging to #{m}"
end def self.create
log("Creating server!")
def self.log(message) end
puts "LOG: #{message}" end
end
end
Server.create
# `create': undefined method `log' for Server:Class (NoMethodError)
115. Callbacks
Module#included
Example: ClassMethods pattern
module Logger class Server
def self.included(m) include Logger
m.extend(ClassMethods)
end def self.create
log("Creating server!")
module ClassMethods end
def log(message) end
puts "LOG: #{message}"
end
end
end
Server.create
# LOG: Creating server!
116. Callbacks
Module#extended
module One
def self.extended(obj)
puts "#{self} has been extended by #{obj}"
end
end
Object.new.extend(One)
# One has been extended by #<Object:0x1019614a8>
117. Callbacks
Class#inherited
class Parent
def self.inherited(o)
puts "#{self} was inherited by #{o}"
end
end
class Child < Parent
end
# Parent was inherited by Child
120. Callbacks
Kernel#caller
def one
two
end
def two
method name
three
file name line (optional)
end
def three
p caller
end
# ["method.rb:156:in `two'", "method.rb:152:in `one'", "method.rb:163"]
https://github.com/joshbuddy/callsite
123. There and back again, a
parsing tale
gem install ruby_parser
gem install sexp_processor
gem install ruby2ruby
Let’s go!
124. There and back again, a
parsing tale
Parsing
require 'rubygems'
require 'ruby_parser'
RubyParser.new.process("'string'")
s(:str, "string")
Type Arguments...
125. There and back again, a
parsing tale
Parsing
require 'rubygems'
require 'ruby_parser'
RubyParser.new.process("'string'")
s(:str, "string")
[:str, "string"] # Sexp
Sexp.superclass
# Array
126. There and back again, a
parsing tale
Parsing
RubyParser.new.process("'string' + 'string'")
s(:call, s(:str, "string"), :+, s(:arglist, s(:str, "string")))
Method Method
Receiver Arguments
call name
127. There and back again, a
parsing tale
Parsing
RubyParser.new.process("'string' + 'string'")
s(:call, nil, :puts, s(:arglist, s(:str, "hello world")))
Method Receiver Method
Arguments
call name
128. There and back again, a
parsing tale
And, back again...
require 'rubygems'
require 'ruby2ruby'
Ruby2Ruby.new.process [:str, "hello"] # => "hello"
129. There and back again, a
parsing tale
And, back again...
require 'rubygems'
require 'ruby2ruby'
Ruby2Ruby.new.process [:str, "hello"] # => "hello"
Ruby2Ruby.new.process [:lit, :symbol] # => :symbol
130. There and back again, a
parsing tale
Roundtrip
require 'sexp_processor'
require 'ruby2ruby'
require 'ruby_parser'
class JarJarify < SexpProcessor
def initialize
self.strict = false
super
end
def process_str(str)
new_string = "YOUZA GONNA SAY #{str[-1]}"
str.clear
s(:str, new_string)
end
end
131. There and back again, a
parsing tale
Roundtrip
class JarJarify < SexpProcessor
def initialize
self.strict = false
super
end
def process_str(str)
new_string = "YOUZA GONNA SAY #{str[-1]}"
str.clear
s(:str, new_string)
end
end
ast = RubyParser.new.process('puts "hello"')
Ruby2Ruby.new.process(JarJarify.new.process(ast))
# => puts("YOUZA GONNA SAY hello")
132. There and back again, a
parsing tale
Roundtrip
class JarJarify < SexpProcessor
def initialize
self.strict = false
Process type :str
super
end
def process_str(str)
new_string = "YOUZA GONNA SAY #{str[-1]}"
str.clear
s(:str, new_string) Consume the current sexp
end
end Return a new one
ast = RubyParser.new.process('puts "hello"')
Ruby2Ruby.new.process(JarJarify.new.process(ast))
# => puts("YOUZA GONNA SAY hello")