Skip to content

Latest commit

 

History

History
258 lines (191 loc) · 4.12 KB

cheap_advice.slides.textile

File metadata and controls

258 lines (191 loc) · 4.12 KB

!SLIDE
!TITLE Cheap Advice

Cheap Advice

!SLIDE
!TITLE Clean Code

Clean Code

@ ruby

class MyClass
def foo; 42; end
end
class MyOtherClass
def bar; 43; end
end
a = MyClass.new
b = MyOtherClass.new
a.foo
b.bar

@

!SLIDE
!TITLE Add Logging

Add Logging

@ ruby

class MyClass
def foo
$stderr.puts “#{self}#foo => 42”
42
end
end
class MyOtherClass
def bar
$stderr.puts “#{self}#bar => 43”
43
end
end
a = MyClass.new
b = MyOtherClass.new
a.foo
b.bar

@

!SLIDE
!TITLE Add Security

Add Security

@ ruby

class MyClass
def foo
raise “SecurityError” unless $roles.include?(“MyClass#foo”)
$stderr.puts “#{self}#foo => 42”
42
end
end
class MyOtherClass
def bar
raise “SecurityError” unless $roles.include?(“MyClass#bar”)
$stderr.puts “#{self}#bar => 43”
43
end
end
a = MyClass.new
b = MyOtherClass.new
$roles = [ “MyClass#foo” ]
a.foo
b.bar

@

!SLIDE
!TITLE YUCK!

YUCK!

@ ruby

class MyClass
def foo

  1. YUCK!: raise “SecurityError” unless $roles.include?(“MyClass#foo”)
  2. YUCK!: $stderr.puts “#{self}#foo => 42”
    42
    end
    end
    class MyOtherClass
    def bar
  3. YUCK!: raise “SecurityError” unless $roles.include?(“MyClass#bar”)
  4. YUCK!: $stderr.puts “#{self}#bar => 43”
    43
    end
    end
    a = MyClass.new
    b = MyOtherClass.new
    $roles = [ “MyClass#foo” ] # ???
    a.foo
    b.bar

@

!SLIDE
!TITLE Dumb and Clean, Smart and Dirty

Dumb and Clean, Smart and Dirty

  • Real World is Smart Code.
  • Dumb Code is Clean, Smart Code is Dirty.
  • Get Dirt Out Of Code — (problem-domain vs. solution-domain)
  • Sweep It Somewhere Else — (modularize the smart dirt)
  • Don’t be Dirty All the Time — (dynamic, stateful dirt: logging, debugging, security, etc.)

!SLIDE
!TITLE Separation of Concerns

Separation of Concerns

  • Logging
  • Security

… are not problem-domain issues.

!SLIDE
!TITLE Advice

Advice

  • Commonplace in the Lisp world, (esp. Emacs).
  • Advice is function that wraps another function: “before”, “after” or “around”.
  • Advice can be added or removed at run-time.

!SLIDE
!TITLE Advice != Aspects

Advice != Aspects

  • Aspects are woven into code based on complex “codepoint” criteria at build-time (or load-time).
  • Advice is applied to a more well-known constructs: applicable objects: functions, methods, etc.
  • Advice are objects.
  • Advice can be added and removed at run-time.

!SLIDE
!TITLE Cheap Advice

Cheap Advice

  • … adds dynamic Advice to Ruby methods.
  • … is applied to methods.
  • … are stateful objects.
  • … can be added and removed at run-time.
  • … are configurable.

!SLIDE
!TITLE Logging Advice

Logging Advice

@ ruby

  1. Advice
    trace_advice = CheapAdvice.new(:around) do | ar, body |
    ar.advice[:log] <<
    "#{Time.now.iso8601(6)} " <<
    “#{ar.rcvr.class} #{ar.meth} #{ar.rcvr.object_id}\n”
    body.call
    ar.advice[:log] <<
    "#{Time.now.iso8601(6)} " <<
    "#{ar.rcvr.class} #{ar.meth} #{ar.rcvr.object_id} " <<
    “=> #{ar.result.inspect}\n”
    end
  2. State attached to trace_advice.
    trace_advice[:log] = File.open(“trace.log”, “a+”)

@

!SLIDE
!TITLE Applying Advice

Applying Advice

@ ruby

  1. Activate trace_advice:
    trace_advice.advise!(MyClass, :foo)
    trace_advice.advise!(MyOtherClass, :bar)
    a.foo
    b.bar
  1. Disable trace_advice:
    trace_advice.disable!
    a.foo
    b.bar
    @

!SLIDE
!TITLE Configuration

Configuration

@ yaml

:advice:
~:
:enabled: false
:options:
:trace:
:logger:
:name: :default

‘MyClass’: :advice: trace ‘MyClass#foo’: :enabled: false ‘MyClass#bar’: :enabled: false

@

!SLIDE
!TITLE Security Advice

Security Advice

You get the idea.

!SLIDE
!TITLE Example

See example/ex01.rb

!SLIDE
!TITLE CheapAdvice

Questions?

Code!