Code Generation: The Safety Scissors of Metaprogramming

Post on 12-Nov-2014

328 views 0 download

Tags:

description

Metaprogramming is cool. Metaprogramming is hip. Metaprogramming has performance costs and is a serious pain in the butt to debug.You can get a lot of the benefits of metaprogramming from using code generation instead. In fact, most metaprogramming is really just dynamic code generation. Or maybe it’s the other way around. You could say that metaprogramming is really just dynamic code generation, or that code generation is just compiled metaprogramming. Code generation is code which creates text strings of code and saves them to the filesystem; metaprogramming is code which creates text strings of code and passes them directly to eval() or one of its variants.Either way you slice it, code generation is a powerful strategy. Using Ryan Davis’ awe-inspiring library Ruby2Ruby, it’s technically possible to unit test metaprogramming, but unit testing code generation is easier to do. Its results are also a lot easier to debug. Jack Herrington’s brilliant book “Code Generation In Action” demonstrates how you can generate the literally hundreds of Java files a non-trivial EJB application needs with a much smaller number of Ruby programs, slashing development time by months. Several aspects of Rails use code generation extensively, including scaffolding and the rails command itself. Rails’ core strategy of “convention over configuration” would be impossible without code generation.In this talk, I’ll demonstrate both how to unit-test metaprogramming with Ruby2Ruby, nd how to automate EJB application development with Herrington’s code generation techniques. Bring a nice Tupperware bowl to catch your brain in after it leaks out your ears.

Transcript of Code Generation: The Safety Scissors of Metaprogramming

1

Ἀρχιμήδης2

π3

δος µοι πα στω, καιταν γαν κινάσω

4

λ5

λthe ultimate

6

μετά7

meta8

metaprogramming?

9

metaOO

10

Code GenerationThe Safety Scissors

Of Metaprogramming

11

Ruby2Ruby12

(lambda do puts “hello world”end).to_ruby

13

class Widget < ActiveRecord::Baseend

14

Ruby2Ruby.translate(Widget)

15

class Widget < ActiveRecord::Base has_one :fooend

16

Ruby2Ruby.translate(Widget)

17

18

19

20

21

overkil l

22

monkeypatching

23

tangledobject graph

24

stop monkey-patching!

25

nothing can ever protect you

from bad programming

26

nothing can ever protect you

from bad programming

27

28

29

tests

specs30

tests

specsy u need

31

32

tests rawk

33

debuggers suck

34

debuggers suck

35

monkey-patchmonkey-patching

itself

36

meta-monkey-patching

37

rubinius38

nodebox

39

code == data

40

at this point, I just demoed code from my blog.below is a link to the post:

http://gilesbowkett.blogspot.com/2008/03/simple-metaprogramming-logger-with.html(code samples are included)

41

42

simple object graph

43

nodebox

44

tangledobject graph

45

node box

46

same tool

47

different output

48

proof of concept49

50

foo

51

foo

bar

52

foo

barbaz

53

foo

barbaz

foofoo

foo

foo

foo

foo

foo

bar

bar

bar

bar

bar

bar

barbaz

baz

baz

baz

baz

54

debuggers suck

55

some people want debuggers

56

57

“Ruby has no tool support!”

58

1 day

59

shock the monkey

60

Powerful Tools

61

Powerful Tools

• Rubinius

• Nodebox

• code == data

62

Powerful Tools

• Rubinius

• Nodebox

• code == data

63

Powerful Tools

• Rubinius

• Nodebox

• code == data

64

• Rubinius

• Nodebox

• code == data

65

code == data

66

1998

67

generated HTML

68

automated cvs and rcs

69

70

(2003)EJB

71

legacy app: 150 tables

72

ejb: 7 files per entity

73

7 * 150 = 1050 Java files

74

by hand: 3+ man-years

75

generators: 2 man-months

76

77

four generator types

• code munger generator• inline code expansion generator• mixed-code generator• partial-class generator• tier generator

78

generating UIs

79

generating unit tests

80

embedding SQLwith generators

81

creating databaseaccess generators

82

generating webservices layers

83

generating models froma business logic DSL

84

sound familiar?

85

86

script/generate scaffold

87

script/generate resource

88

script/generate plugin

89

script/generate migration

90

script/generate

91

rails Command

92

acts_as_authenticated

93

restful_authentication

94

ActiveRecord SQL

95

ActionPack Helpers•ActiveRecordHelper•AssetTagHelper•AtomFeedHelper•BenchmarkHelper•CacheHelper•CaptureHelper•DateHelper•DebugHelper•FormHelper•FormOptionsHelper

•FormTagHelper•JavascriptHelper•NumberHelper•PrototypeHelper•RecordTagHelper•SanitizeHelper•ScriptaculousHelper•TagHelper•TextHelper•UrlHelper

Text

•RecordIdentificationHelper

96

code generation FTW

97

98

code generation FTW

99

code == data

100

(eq (code (data)))

101

102

functions which return functions which return functions which return functions which return functions which return functions which return functions which return functions which return functions which return functions which return functions which return functions which return functions

103

code which generates data which runs as code which generates data which runs as code which generates data which runs as code which generates data which runs as code which generates data which runs as code which generates data which runs as code

104

105

lisp macros pwn“metaprogramming”

106

and you can dothem in Perl!

107

108

shocked? perl!

109

110

shocked? perl!

111

λthe ultimate

112

combinator113

$114

$small teams

115

$small teams lisp macros

116

great programmers canwrite better programmersthan they can hire

117

great programmers canwrite better programmersthan they can hire

metaprogramming118

great?119

120

intergalactic voluntarily baldclone wizards of time and space

who the womens are be lusting fors

121

122

123

124

incredible power

125

simpleclarity

126

simplicity

magic127

skilled programmers canwrite better programmersthan they can hire

metaprogramming128

129

code which generates data which runs as code which generates data which runs as code which generates data which runs as code which generates data which runs as code which generates data which runs as code which generates data which runs as code

130

Unix.is_a? Lisp

131

# => true

132

133

δος µοι πα στω, καιταν γαν κινάσω

134

Ruby.is_a? πα στω

135

# => true

136

137

138

139

140

141

boba fezz

142

143

Caveats!

• read the book, the technique is easy

• leveraging it is the clever part

• you can use Ruby as well as Rubinius

• if Unix is a Lisp, the filesystem is a compiler

144

Caveats!

• read the book, the technique is easy

• leveraging it is the clever part

• you can use Ruby as well as Rubinius

• if Unix is a Lisp, the filesystem is a compiler

145

Caveats!

• read the book, the technique is easy

• leveraging it is the clever part

• you can use Ruby as well as Rubinius

• if Unix is a Lisp, the filesystem is a compiler

146

Caveats!

• read the book, the technique is easy

• leveraging it is the clever part

• you can use Ruby as well as Rubinius

• if Unix is a Lisp, the filesystem is a compiler

147

Caveats!

• read the book, the technique is easy

• leveraging it is the clever part

• you can use Ruby as well as Rubinius

• if Unix is a Lisp, the filesystem is a compiler

148

149

Essential Technique

• read the book, the technique is easy

• leveraging it is the clever part

• you can use Ruby as well as Rubinius

• if Unix is a Lisp, the filesystem is a compiler

150

Essential Technique

• puts

• leveraging it is the clever part

• you can use Ruby as well as Rubinius

• if Unix is a Lisp, the filesystem is a compiler

151

Essential Technique

• puts

• eval

• you can use Ruby as well as Rubinius

• if Unix is a Lisp, the filesystem is a compiler

152

Essential Technique

• puts

• eval

• ERB

• if Unix is a Lisp, the filesystem is a compiler

153

Essential Technique

• puts

• eval

• ERB

• if Unix is a Lisp, the filesystem is a compiler•(unix pipes)

154

Essential Technique

• open mouth

• make noise

• profit

• if Unix is a Lisp, the filesystem is a compiler

155

156