diff --git a/metaprogramming-ruby-talk/.ipynb_checkpoints/Metaprogramming with Ruby-checkpoint.ipynb b/metaprogramming-ruby-talk/.ipynb_checkpoints/Metaprogramming with Ruby-checkpoint.ipynb
index f3da4c8..1316624 100644
--- a/metaprogramming-ruby-talk/.ipynb_checkpoints/Metaprogramming with Ruby-checkpoint.ipynb
+++ b/metaprogramming-ruby-talk/.ipynb_checkpoints/Metaprogramming with Ruby-checkpoint.ipynb
@@ -21,7 +21,18 @@
}
},
"source": [
- "
"
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "
"
]
},
{
@@ -90,6 +101,17 @@
"Yes, but metaprogramming typically refers to something else in **Ruby**"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "
"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -112,6 +134,31 @@
"Metaprogramming in ruby refers to code that writes code for you **dynamically. At runtime.**"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "Examples:\n",
+ "\n",
+ "* Type Introspection\n",
+ "* Reflection"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "# Metaprogramming In Ruby"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -160,7 +207,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 3,
"metadata": {
"slideshow": {
"slide_type": "fragment"
@@ -202,7 +249,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 5,
"metadata": {
"slideshow": {
"slide_type": "fragment"
@@ -246,9 +293,8 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 7,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -330,12 +376,12 @@
}
},
"source": [
- "This adds 2 new keywords to the Module class: refine and using."
+ "This adds 2 new keywords to the Module class: **refine** and **using**."
]
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 9,
"metadata": {
"slideshow": {
"slide_type": "slide"
@@ -381,7 +427,7 @@
}
},
"source": [
- ""
+ "
"
]
},
{
@@ -478,9 +524,8 @@
},
{
"cell_type": "code",
- "execution_count": 52,
+ "execution_count": 15,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -563,9 +608,8 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 17,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -586,6 +630,17 @@
"bar"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "**define_method** is defined in the **Module** class, which class **Class** inherits from"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -621,9 +676,8 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 20,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -644,11 +698,21 @@
"(1..5).each { |n| send(\"test#{n}\") }"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "**send** is defined in the **Object** class, which all user-defined classes inherits from"
+ ]
+ },
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 22,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "slide"
}
@@ -664,8 +728,6 @@
" end\n",
"end\n",
"\n",
- "# New Code\n",
- "\n",
"okcpython = OKCPython.new\n",
"puts okcpython.send(\"is_boss?\")"
]
@@ -680,7 +742,7 @@
"source": [
"The power here comes when you want to call a method based on some in-scope situation - often times based off of a variable value.\n",
"\n",
- "**Object#send** allows you to call private functions (as you'll see soon). Use **Object#public_send** if you can."
+ "**Object#send** allows you to call private functions. Use **Object#public_send** if you can."
]
},
{
@@ -696,9 +758,8 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 27,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -739,9 +800,8 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 29,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -825,9 +885,8 @@
},
{
"cell_type": "code",
- "execution_count": 59,
+ "execution_count": 32,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "slide"
}
@@ -882,9 +941,8 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": 38,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -897,13 +955,24 @@
"# the normal way\n",
"class Book\n",
" def title\n",
- " \"All My Friends Are Dead\"\n",
+ " \"The Handmaid's Tale\"\n",
" end\n",
"end\n",
"\n",
"puts Book.new.title"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "# 2 Ways to Define a Class"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -917,9 +986,8 @@
},
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": 42,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -938,7 +1006,7 @@
" #Both method declaration types work\n",
" \n",
" define_method('title') do\n",
- " \"All My Friends Are Dead\"\n",
+ " \"The Hobbit\"\n",
" end\n",
"end\n",
"\n",
@@ -970,9 +1038,8 @@
},
{
"cell_type": "code",
- "execution_count": 19,
+ "execution_count": 45,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -985,7 +1052,7 @@
"my_var = \"Success\"\n",
"\n",
"MyClass = Class.new do\n",
- " \"#{my_var} in the class definition\"\n",
+ " puts \"#{my_var} in the class definition\"\n",
" \n",
" # Have to use dynamic method creation to access my_var\n",
" define_method :my_method do\n",
@@ -1026,14 +1093,47 @@
}
},
"source": [
- "Most things in Ruby are objects. Blocks are not. To pass them around, you use the **&** operator"
+ "To get an in-depth explanation:\n",
+ "https://www.youtube.com/watch?v=_2FjxLVLfhs"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "# Closures: Blocks, Procs, & Lambdas"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "Most things in Ruby are objects. Blocks are not."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "However, there are 2 callable structures that relate to blocks: Procs and Lambdas."
]
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": 47,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1111,22 +1211,15 @@
},
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 49,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "80\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
+ "%%capture\n",
"%%ruby\n",
"\n",
"def lambda_example\n",
@@ -1140,9 +1233,8 @@
},
{
"cell_type": "code",
- "execution_count": 24,
+ "execution_count": 57,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1233,9 +1325,8 @@
},
{
"cell_type": "code",
- "execution_count": 26,
+ "execution_count": 62,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1277,16 +1368,15 @@
}
},
"source": [
- "Even with Open Classes and Dynamic Class creation, we couldn't update a class within another closure (like a method). We also couln't get into a class based on a variable - we had to use the constant.\n",
+ "Even with Open Classes and Dynamic Class creation, we couldn't update a class within another closure (like a method).\n",
"\n",
"Until now."
]
},
{
"cell_type": "code",
- "execution_count": 28,
+ "execution_count": 68,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1307,6 +1397,52 @@
"puts \"foo\".m"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "# Class Eval"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "With class_eval, we can also get into a class based on a string variable - instead of the constant."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 74,
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "%%capture\n",
+ "%%ruby\n",
+ "\n",
+ "def add_method_to(a_class)\n",
+ "\n",
+ " Kernel.const_get(a_class).class_eval do\n",
+ " def m; 'Hello!'; end\n",
+ " end\n",
+ "end\n",
+ "\n",
+ "add_method_to(\"String\")\n",
+ "puts \"foo\".m"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -1344,9 +1480,8 @@
},
{
"cell_type": "code",
- "execution_count": 29,
+ "execution_count": 76,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1375,9 +1510,8 @@
},
{
"cell_type": "code",
- "execution_count": 32,
+ "execution_count": 78,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1428,9 +1562,8 @@
},
{
"cell_type": "code",
- "execution_count": 34,
+ "execution_count": 60,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1475,9 +1608,8 @@
},
{
"cell_type": "code",
- "execution_count": 35,
+ "execution_count": 80,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1529,7 +1661,7 @@
"\n",
"https://github.com/alkrauss48\n",
"\n",
- "https://thesocietea.org"
+ "https://thecodeboss.dev"
]
}
],
diff --git a/metaprogramming-ruby-talk/Metaprogramming with Ruby.ipynb b/metaprogramming-ruby-talk/Metaprogramming with Ruby.ipynb
index f3da4c8..1316624 100644
--- a/metaprogramming-ruby-talk/Metaprogramming with Ruby.ipynb
+++ b/metaprogramming-ruby-talk/Metaprogramming with Ruby.ipynb
@@ -21,7 +21,18 @@
}
},
"source": [
- "
"
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "
"
]
},
{
@@ -90,6 +101,17 @@
"Yes, but metaprogramming typically refers to something else in **Ruby**"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "
"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -112,6 +134,31 @@
"Metaprogramming in ruby refers to code that writes code for you **dynamically. At runtime.**"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "Examples:\n",
+ "\n",
+ "* Type Introspection\n",
+ "* Reflection"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "# Metaprogramming In Ruby"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -160,7 +207,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 3,
"metadata": {
"slideshow": {
"slide_type": "fragment"
@@ -202,7 +249,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 5,
"metadata": {
"slideshow": {
"slide_type": "fragment"
@@ -246,9 +293,8 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 7,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -330,12 +376,12 @@
}
},
"source": [
- "This adds 2 new keywords to the Module class: refine and using."
+ "This adds 2 new keywords to the Module class: **refine** and **using**."
]
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 9,
"metadata": {
"slideshow": {
"slide_type": "slide"
@@ -381,7 +427,7 @@
}
},
"source": [
- ""
+ "
"
]
},
{
@@ -478,9 +524,8 @@
},
{
"cell_type": "code",
- "execution_count": 52,
+ "execution_count": 15,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -563,9 +608,8 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 17,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -586,6 +630,17 @@
"bar"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "**define_method** is defined in the **Module** class, which class **Class** inherits from"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -621,9 +676,8 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 20,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -644,11 +698,21 @@
"(1..5).each { |n| send(\"test#{n}\") }"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "**send** is defined in the **Object** class, which all user-defined classes inherits from"
+ ]
+ },
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 22,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "slide"
}
@@ -664,8 +728,6 @@
" end\n",
"end\n",
"\n",
- "# New Code\n",
- "\n",
"okcpython = OKCPython.new\n",
"puts okcpython.send(\"is_boss?\")"
]
@@ -680,7 +742,7 @@
"source": [
"The power here comes when you want to call a method based on some in-scope situation - often times based off of a variable value.\n",
"\n",
- "**Object#send** allows you to call private functions (as you'll see soon). Use **Object#public_send** if you can."
+ "**Object#send** allows you to call private functions. Use **Object#public_send** if you can."
]
},
{
@@ -696,9 +758,8 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 27,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -739,9 +800,8 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 29,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -825,9 +885,8 @@
},
{
"cell_type": "code",
- "execution_count": 59,
+ "execution_count": 32,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "slide"
}
@@ -882,9 +941,8 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": 38,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -897,13 +955,24 @@
"# the normal way\n",
"class Book\n",
" def title\n",
- " \"All My Friends Are Dead\"\n",
+ " \"The Handmaid's Tale\"\n",
" end\n",
"end\n",
"\n",
"puts Book.new.title"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "# 2 Ways to Define a Class"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -917,9 +986,8 @@
},
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": 42,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -938,7 +1006,7 @@
" #Both method declaration types work\n",
" \n",
" define_method('title') do\n",
- " \"All My Friends Are Dead\"\n",
+ " \"The Hobbit\"\n",
" end\n",
"end\n",
"\n",
@@ -970,9 +1038,8 @@
},
{
"cell_type": "code",
- "execution_count": 19,
+ "execution_count": 45,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -985,7 +1052,7 @@
"my_var = \"Success\"\n",
"\n",
"MyClass = Class.new do\n",
- " \"#{my_var} in the class definition\"\n",
+ " puts \"#{my_var} in the class definition\"\n",
" \n",
" # Have to use dynamic method creation to access my_var\n",
" define_method :my_method do\n",
@@ -1026,14 +1093,47 @@
}
},
"source": [
- "Most things in Ruby are objects. Blocks are not. To pass them around, you use the **&** operator"
+ "To get an in-depth explanation:\n",
+ "https://www.youtube.com/watch?v=_2FjxLVLfhs"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "# Closures: Blocks, Procs, & Lambdas"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "Most things in Ruby are objects. Blocks are not."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "However, there are 2 callable structures that relate to blocks: Procs and Lambdas."
]
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": 47,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1111,22 +1211,15 @@
},
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 49,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "80\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
+ "%%capture\n",
"%%ruby\n",
"\n",
"def lambda_example\n",
@@ -1140,9 +1233,8 @@
},
{
"cell_type": "code",
- "execution_count": 24,
+ "execution_count": 57,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1233,9 +1325,8 @@
},
{
"cell_type": "code",
- "execution_count": 26,
+ "execution_count": 62,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1277,16 +1368,15 @@
}
},
"source": [
- "Even with Open Classes and Dynamic Class creation, we couldn't update a class within another closure (like a method). We also couln't get into a class based on a variable - we had to use the constant.\n",
+ "Even with Open Classes and Dynamic Class creation, we couldn't update a class within another closure (like a method).\n",
"\n",
"Until now."
]
},
{
"cell_type": "code",
- "execution_count": 28,
+ "execution_count": 68,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1307,6 +1397,52 @@
"puts \"foo\".m"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "# Class Eval"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "source": [
+ "With class_eval, we can also get into a class based on a string variable - instead of the constant."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 74,
+ "metadata": {
+ "slideshow": {
+ "slide_type": "fragment"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "%%capture\n",
+ "%%ruby\n",
+ "\n",
+ "def add_method_to(a_class)\n",
+ "\n",
+ " Kernel.const_get(a_class).class_eval do\n",
+ " def m; 'Hello!'; end\n",
+ " end\n",
+ "end\n",
+ "\n",
+ "add_method_to(\"String\")\n",
+ "puts \"foo\".m"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -1344,9 +1480,8 @@
},
{
"cell_type": "code",
- "execution_count": 29,
+ "execution_count": 76,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1375,9 +1510,8 @@
},
{
"cell_type": "code",
- "execution_count": 32,
+ "execution_count": 78,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1428,9 +1562,8 @@
},
{
"cell_type": "code",
- "execution_count": 34,
+ "execution_count": 60,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1475,9 +1608,8 @@
},
{
"cell_type": "code",
- "execution_count": 35,
+ "execution_count": 80,
"metadata": {
- "collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
@@ -1529,7 +1661,7 @@
"\n",
"https://github.com/alkrauss48\n",
"\n",
- "https://thesocietea.org"
+ "https://thecodeboss.dev"
]
}
],
diff --git a/metaprogramming-ruby-talk/assets/clevyr-fox.png b/metaprogramming-ruby-talk/assets/clevyr-fox.png
new file mode 100644
index 0000000..152d282
Binary files /dev/null and b/metaprogramming-ruby-talk/assets/clevyr-fox.png differ
diff --git a/metaprogramming-ruby-talk/assets/clevyr.png b/metaprogramming-ruby-talk/assets/clevyr.png
index 972466d..58b0fdb 100644
Binary files a/metaprogramming-ruby-talk/assets/clevyr.png and b/metaprogramming-ruby-talk/assets/clevyr.png differ
diff --git a/metaprogramming-ruby-talk/assets/wiki.png b/metaprogramming-ruby-talk/assets/wiki.png
new file mode 100644
index 0000000..3505489
Binary files /dev/null and b/metaprogramming-ruby-talk/assets/wiki.png differ