How was lunch? Good. I want to start asking everyone a question. When was the last time you worked on a non-productive project just for the fun of it? I'll just think about it for a second. Today I'm going to tell you a story about the last time I did. Let's go back to February 14th of this year. It was a cold Friday night, and also Valentine's Day. If you have a partner, you're probably having a romantic dinner. Whereas if you were single, like I was back then, you were most likely doing less exciting stuff, like spending the night on the Internet. So there I was, on Reddit. After browsing for a while, I stumbled upon this thing called Twitch Place Pokemon. I saw this screen and it was very, very weird. It took me a while to figure out what was going on. Apparently, some dude hooked up a Gameboy emulator to a streaming website and allowed everybody to control it through the chat system. Hundreds of thousands of people were playing Pokemon Game at the same time, the same session. My first thought when I saw this was, oh, my God, this is awesome. My second thought was, I need to make my own. My name's Jose Tomás Salvornoz, and today I'm going to tell you a story of how I've built my own Twitch Place Pokemon. So Saturday morning, I woke up early and went to my bookshelf. I went to my cookbook. Not an ops cookbook, but more of a developer cookbook. And I headed today how to make a Twitch Place Pokemon recipe. The ingredients list reads, we need one Gameboy emulator, one screen streaming application, and one Internet control for the emulator. For the Gameboy emulator, I already knew which I would advance. So that was simple. It's just a simple regular C Gameboy emulator. For the screen streaming, I had no idea how to do it, but I didn't really care because it was probably trivial. So I just skipped it. The real challenge was figuring out how to control the emulator with Ruby. The first thing that popped into my mind is, how the heck do I control an emulator with Ruby? Can I even control my Mac with Ruby? After Googling for a while, I ended up in this Stack Overflow question, called, how do I send keystrokes from a Ruby application? The solution, rather than the lines of, you could use the FFI gem to load user32.dll. Let me read that back again. You could use the FFI gem to load user32.dll. That was clear. Oh, no. That does the job. Just what I needed for a Lucas deep-rim. That does the job, actually, but not for me. There's a couple problems with the Windows solution. Well, first of all, it's Windows. I'm actually locked to the operative system, and I don't like that. The second one is to have no Windows machine. Yeah, and I want to stay like that for the next 30 years. And the third one is that I want to run this on a headless server, on a server with no desktop environment. And yeah, with Windows, that's not possible. So Windows, this solution was definitely a no-go to me. I scrolled a bit more, and I found what this guy wrote. He said you could use JRuby to use the Java robot class to control the keyboard. I had some experience porting some code from Java to JRuby. So by the end of the day, I had a working emulator. I had a working Sinatra application that could send keystrokes, like if I was pressing keys on my computer. So yeah, here you can see it working. It's just some Java bindings, and then whenever I send a request to a specific URL, it will just press the key. You can see it here working. Oops, there's some audio. No, it's fine. You can lower it down. So yeah, so here we see the system working. On the left side, you can see me sending HTTP requests from my iPhone to the Sinatra application, and on the right side, you can see Sinatra actually controlling the Gameboy emulator. Yay! This is a... This is already, like, enough. This is the first prototype. I just built my minimal viable product, but before going to VCs, there's a couple problems that I need to solve. The first one is that simulating keystrokes is a rather weak way of controlling the emulator. If by some reason another window pops up, the focus shifts to that window, so then all the keystrokes that I sent will go to the other window and not to the emulator, which is not what we want. It still requires depth of environment, so we... Well, first of all, we need to position the emulator in a specific part of the screen.  It's not viable. It's just too much effort. Lots of things can go wrong. And the third one, which is the most important one, there's a huge latency. If we're recording the screen, like recording video from the screen, besides recording a specific area, people usually have to load buffer the video for like, I don't know, 10 to 20 seconds, and that adds enough delay. So what you're seeing in the screen, so when you're playing the Twitch Play Pokémon thing, you see the emulator and you send commands on the chat for what you're seeing, but what you're seeing now happened 20 seconds ago, so that's not possible. Imagine playing Counter-Strike with a 20-second delay. It just wouldn't work. So, yeah, let's think a bit for a while. What would be the perfect emulator for us? The perfect emulator would be one that requires no desktop environment. Yeah, just hold that problem. It streams the video online and has an API that allows us to send button presses so we can run on a headless server. I couldn't find one that does that. So I went back to my cookbook and I saw this very small notice at the bottom that it said, for a headless recipe, flip the page. Did so. And there it was. This is the ingredients list for building our own Twitch Play Pokémon that requires a headless emulator, which is just having the headless emulator. If you write the emulator yourself, then you can control everything. Let me go back a couple of steps and let's explain a bit what's an emulator. Yeah. So, an emulator is a software that allows us to run Game Boy games in our computer. If in a Game Boy, we have a cartridge in the Game Boy emulator, we have a ROM file which has the exact same binary contents that are in the original Game Boy cartridge. The only way that I know to run the same binary in the computer is achieved by emulating the Game Boy hardware. So if in the Game Boy, we have the CPU, GPU and RAM, we need to do the same thing for a Game Boy emulator. When you... What happens in the real Pokémon, in the real emulator, I mean in the real Game Boy, when you put the game on, is that the console dumps the whole cartridge into the RAM. If we want to write our own emulator, we need to do the exact same thing, which is quite nice. We just dump the whole binary file into a big array. Okay, so... Yeah, so when you load the emulator or the Game Boy, the CPU of the Game Boy loads the first byte of the RAM and compares it in an instruction table. The instruction table is like a hard-coded list of instructions that the CPU has which are all the things that the CPU can do. These are just very small actions, like for example, in the byte 0xC0, the instruction according to that byte will just jump the execution to another sector of the game. In our Ruby version, we have to do the exact same thing. So the whole... This is what I call the loop, which is how emulators work, and also CPUs. The first thing that you do is that... Well, the CPU has this internal variable, which is called the program counter. Each time it executes an instruction, then it will increase the number so it knows what byte to read. When we run the emulator, we just load the first byte and then see what part of the RAM is the value for that byte. Then we read the byte and see to what corresponds to in our instructions table. Then we execute the CPU command and then we increase the program counter by one. I call this the loop because I have no computer science background, but this is what it means to me. And what's cool about this is that this is the basics of how computers work from the Turing machine to your Mac, to your Game Boy, and I have no idea about this. And I've been developing professionally for at least three years. How do we care about how emulators work? Because we have to build our own. Because we'll have to write our own. So what are the advantages of having our own emulator? First of all, we don't need to emulate key presses because as we control the emulator, we control the way the keys are emulated. So we just... Yeah, we just emulate them like that. We can build our own API. Second of all, we can run on a headless server because we don't need to output the actual screen of the Game Boy to the real screen. We can just pipe it to a web socket and render it with Canvas, for example. Third of all, we can stream closer to real time because we don't really have to record the screen who can just output the bytes in a compressed way, which is probably much more faster than streaming video. And the most cool part about this is that we control the memory. For example, as we have the whole RAM of the Game Boy, we can have some version control system. So something very common that people do when they play Game Boy is that they save, they do something, and then if something fails, they just go back. As we have the RAM, we can just take snapshots and then rewind whenever we want. We can do this online, which is quite cool. We can also... What's the next one? We can also fork and branch. So it's pretty much the same. You could do it with Git, all of this you can do more or less with the current Game Boy simulators, but they're not really meant for that. But all of this gets much, much more interesting when we introduce machine learning to the equation. This guy, which is called Tom Murphy, he wrote a PhD paper based on a program that he wrote that plays Mario itself. The way he did it is that he got hooked up into a NES emulator, and then he analyzed the way the RAM works. When you play Mario, you just want the score to go higher and higher and higher. So he looked up the section of the RAM that just goes higher whenever he advances in the game. He introduced a machine learning algorithm that just tries different things and learns based on how you play the game, so as to play the game itself. This is actually quite interesting. You can make the software that can finish up to two levels of Mario without human intervention, which is really, really nice. The URL is over there if you want to check it out. So, yeah, what are the advantages of having our own emulator? No need for a key process, we can run on a headless server, we can stream online, and yeah, we control the memory. Am I forgetting something? Oh, okay. All of this is awesome. We have the ingredients, and we know what to do. There's only one problem, though.  Like every developer, I guess. Luckily, Barucho came to the rescue. The conference was announced, and I didn't have enough money to get my own ticket. After running on Twitter for a while, Chuz told me, well, man, the CSP is open. If you send a proposal and you make it, we'll get you in for free. Here. It reminds me a bit of what Matt said this morning. When he got the funding for M-Ruby, that was the exact same case. Well, he didn't do it for the money, but he had the goal, he had the deadline, which is, yeah. So, yeah, my tag got selected, and this is when the fun really began. I committed to give a talk in a conference for a project that I always spent working a weekend on it, and I had no real clue how long it would take me to write it. I made this a small comic based on Y's book that pretty much expresses how I felt. So, taking over Mimey. Let me introduce you to Hanno Gonzalez. Hanno Gonzalez is Chilean. He's a Chilean developer. He loves Game Boy, he loves Pokémon, and he loves Ruby. Hanno had been working for a couple months on this project called Mimey, which is a Game Boy emulator written in Ruby, which is exactly what we want. I'm going to go ahead and run up the emulator. It was still better than starting from scratch, so I just forked Mimey and continued working on my own. Hanno was following a tutorial called Game Boy Emulation in JavaScript. The tutorial was quite nice, or it seems so. The way the tutorial works is that it takes you through every component of the Game Boy hardware, teaches you how it works, and then how to write the beginning, you can write the component yourself. It didn't take me long... Well, it was reasonable to think that by following a JavaScript tutorial, I could write the same thing in Ruby. It didn't take me long to figure out that the JavaScript Game Boy emulator tutorial was more like along the lines of how to draw an old tutorial. First, you draw some circles, and then you just add the rest of the oil. The tutorial was pointless. So, today I'm going to tell you a couple stories that happened during the development of this emulator. The first one is about bits and bytes. I have no computer science degree. Oh, um... As soon as I got into the development of the emulator, I figured out that the words bits and bytes were everywhere. I have no computer science background, so actually, I had no idea what's a bit in a byte, which was probably fine, right? Like, I'm a web developer, I'm a Rails developer, I don't really deal with such things in my daily life. But that's the first thing that they teach you when you go into computer science. I live in Berlin, and I'm a Rails skills coach, so I happen to go to Travis every Monday. All right, so I had no real reason to know what that means. But I was forced to learn it this time. So, yeah, I seek for help. Let me introduce you to Sven Fuchs. He knows about computers, right? He actually knows more than about computers. He knows a lot about computers. So I went to him in Travis, and I asked him, Sven, what's the difference between a bit and a byte? What's the word? And he told me... I learned that 20 years ago. I asked him for an example of when did he actually use what's a bit and a byte, and he couldn't think of any. And I don't think he's wrong. If you don't have to use it, you can use it. Sadly, if you're writing an emulator, you actually have to deal with such things. Sven explained me the difference, and then I moved on with the development of the emulator. Let me talk about what's irresponsible Ruby. Last year, in Yerukko... Oh, this is his tip-clapnik. He also knows a lot about computers, and he gave a talk in Yerukko last year. He introduced us to the concept of irresponsible Ruby. He's inspired by Y. Irresponsible Ruby code in Steve is Ruby code that you wouldn't deploy at your day job because it's just too interesting or creative. I like the idea a lot. Irresponsible Ruby is Ruby code that uses neat hacks, weird metaprogramming, unusual techniques, and no unit testing. I like the concept a lot. Oh, one more quote. He actually also quote Y. If you're worried too much about being clean and tidy, you can't push the boundaries, which was exactly what I wanted to do with my project. Hannah was testing the Miami emulator using RSpec for every CPU instruction, which are like 200 or something. It was just ridiculous to do it that way, and it was stopping me from actually developing the emulator. So I like the concept of irresponsible Ruby a lot, so I wanted to apply it from this project. So the next story I'm going to tell you is about how to test irresponsibly. Each time, so I explained the loop, and the CPU follows all the steps. The CPU has usually six registers, which are like variables, which are just very, very tiny numbers, one byte, and after every instruction, they change a bit. So for example, between the first and the second instruction, no number changed, but between the second and the third one, the instruction was decrement the byte B, so you can see the number goes from 22 to 21. These are instructions. I thought that I could run the JavaScript version that was working, the end result of the tutorial, and just store those numbers and then do the same for my Ruby version and compare them and see what could go wrong, when it was going wrong. Yeah, I did that. Luckily, the specification of how the original Game Boy works was feature frozen before I was born, so it wasn't going to fail. Let me take you through my development process. I actually did TDD with this tool. The way I worked is that I run the test, I saw it failed, fix the CPU instruction, and then just repeat. This is the debugger I wrote for myself. It runs the node version, then it runs the Ruby version, and then it compares the result of each CPU instruction. In this case, the number should have been six, but it was one. I just fixed that, and then it was working again. So, let me tell you the story about rendering the first image. Some people say that men who grow a beard are full of patients, because of all the time it takes them to grow that beard. If you think that's patients, try spending weeks writing a Game Boy emulator, which is supposed to be fun, just seeing hexadecimal addresses, and you really know what patience means before rendering any image. Just addresses. That's patience to me. It usually takes about 50,000 CPU instructions, so you can start seeing the first frame of the emulator. And it was the moment. I knew that the code was ready to render the first image, so I ran the test with and it was supposed to be working. So I crossed my fingers, and I set it up in such a way that it just had to press enter, and then I would see the first image. Let's see what happened. It failed. It's a bit frustrating to spend like months working on something, and then when it's supposed to be working, you just see something blank. I didn't really know what was going on, because the code was exactly the same. The memory was exactly the same as it was in the JavaScript version. It was working, but it was still not working. What I didn't take it to consideration is that the JavaScript version is supposed to render in Canvas, which in practice means that one every four pixels has actual information, and the rest was just Neil, who had a screen. Dividing some number by four would actually do the job. I don't know why, but I would just get the fourth pixel and that was enough. So here we go again. Fix the test. Well, I supposedly fixed the emulator. Same process. I just had to press enter this time a couple more steps, and I should see an image. Coding DHH. If you stretch it a bit more, you could see what was going on. You could see some shape, but it was still a bit weird. If I stretch it even more, you would see this. I had no real output screen, so I just made up this simple system so it renders to my terminal. This was the first frame that the Gameboy emulator was showing, which was great. After doing this, I felt like the king of the world, right? I spent months working on this, and I had to write all of that. And I could see this image. This is like my little baby. I was still looking forward for the Baruka conference. I was very excited. This time, I was going to finish the emulator for reels in one week. At least that's the way I felt. Funny enough, before doing this project, I looked for a headless emulator written in Ruby, and I couldn't find any. I was going to be able to say that this was the first Gameboy emulator in Ruby. And not just written in Ruby, but also in the HH. It just uses Ruby everywhere. It would be full of Ruby. Which was awesome. Just to make sure, I decided to go to GitHub once more, and I typed Gameboy emulator. 237 results. No surprise, right? There's lots of emulators. It's a common thing. You can see all the languages that are available, and Ruby wasn't on the list. So I thought, okay, that's pretty safe. But then I thought, what if... So I chose JavaScript, and I changed the JavaScript part in the URL to Ruby. And then I hit Enter. And that's when I see it. Two results. Actually, the second one is nothing. It's like an empty project. But the first one, this Rampan monkey guy actually did it. Have you seen the Simpsons episode where you can see Ralph's heart being heartbroken? That's exactly how I felt. Yeah, it was horrible. I had no idea what to do. I was supposed to come here and tell you, I wrote this Gameboy emulator and Ruby, which I partly did, right? I was turned into my first image. But, yeah, I was very, very, very demotivated. What this Rampan monkey guy did was just perfect. He was actually following the very same tutorial, and he finished it. Even had that graphical interface, and you can even see the same thing over there. I learned my lesson. Do a more deep research before writing a whole emulator. Yeah. So, yeah, I felt horrible, right? It took me a couple of days to realize that actually what I did, it was still great. I learned a lot by doing this project, I learned tons of things that I never would have that I would have never learned by my own. I'm a very lazy person, I have no problem admitting that. If you give me a book with the exact same information that I learned, I would have just not done it. I need a practical project, and being pushed just like that to us, and having a deadline actually helped me, you know, actually do the thing. I had to be very consistent, sit down every day, and work on the emulator. I also got out of my comfort zone. This is my first conference talk, and, yeah, it's not something easy to do. You work for a long time on something, and, yeah, I really wanted to go to Barucho, so, yeah, I did it for Barucho, and, yeah, it was actually quite fun. It's really neat to see something going from, I don't know, seven CPU instructions. You can sort of measure your progress, right? At least I did in CPU instructions. At the beginning I did seven CPU instructions. Then the first 100, then the first 1,000, and then 50,000. That's great just to see your progress and, yeah, just doing a Game Boy emulator. It's also a really nice topic to talk with people with. Last night in the speakers' dinners we were all talking about, like, what's her talk about, and somebody asked me, so what's your talk about? And I said, oh, I just wrote a Game Boy emulator in Ruby. And that was it. They just got it immediately. I can also apply some of this to my work. It's like it's given that I'm not going to need a late 80s GPU for my startup. But, for example, it's quite nice to know how to use bitmasks and what an hexadecimal address really, really means. And, yeah, how it works in the computer. Which is quite neat. I also learned the concept of conference ribbon development. Quoted by Tim O'Reilly, I can really tell you, man, this thing works. Most of this talk was finished just a couple of years ago. And, yeah, I kept polishing even until five minutes. And, yeah, if you need to get something done, just tell somebody you're going to do it and make sure that there's no way for you to back off of that. And, yeah, I just feel that sometimes you just need the right push to do things. Which I mean, you know it, but you still don't know it, right? Ultimately, I realized that the journey is the destination. And, yeah, it's just a little process that I followed rather than the result. I'm still standing here and I still have all this knowledge that I got, which the outcome is almost the same. Just before closing, I want to tell, like, a short story of the process that I had when I was, like, yeah, I was 14 years old when I started working as a freelancer. Somebody would come to me asking for a website with specific features. I was just getting into BHP, so I had no idea how to do them. But I still promised to do them nonetheless. And, yeah, I was going to get the money and then do whatever. I also had a deadline and, yeah, I promised the person I would do the features and then I just learned how to do them and then got paid for it. I did that very, very, very often, lots of times, and ultimately I knew all I had to do. At some point, I stopped over-promising because I had so much experience in doing what I was promising, which I think it's great. This project reminded me of the exact same thing. When I committed to do a Game Boy emulator, I had no idea how difficult it would be. I mean, I knew it was difficult. I didn't know it was going to be that difficult. But, yeah, I learned. Now I know how computers work, which is very useful if you're a developer. And I think that's the core message that I want to give you today. Just do projects for fun. Who needs a Game Boy emulator nowadays? It doesn't give you money, but you still learn a lot out of it. I feel it helps to grow a lot. So, yeah, I want to invite all of you to wear the hacker hat. Write irresponsible Ruby and get back the passion that you started into programming. Thanks a lot. What is the get-up repository of the emulator, if it's public? I can't show it anymore, but my Twitter handle is eljojo. You can go to github slash eljojo slash Miami. It's a quite nice thing to just dig into the code, and, yeah, it's actually horribly written, but, yeah, you can render a first frame in Game Boy, which is good enough. Any more questions? I want to know, would you do a conference-driven development again? Would you do the same thing of signing up for talk eight months in advance and then have to kill yourself every day to get there, or is that a one-off? Can we expect this as a regular thing?  Yeah, it's great. The problem of living in Berlin is that there's so many things to do that you postpone everything, right? Because there's Ruby Meetups, events, whatever. I had to learn how to be consistent and spend the time. I'm a horrible procrastinator, and this helped me a lot. Big round of applause for Jose.


We have been told many times about mili-curie, run-t-in, mili-run-t-in, rem, whatever, the units, but we don't know anything. Well, I know that radiation is bad for health. Even low doses affect health. I read about it in the local paper. I'm not afraid either of radiation or anything else in the world. What can I know about it when science knows to leak about it? Panic was tremendous because of radiation. No one could judge what harm it can do and what happens afterwards. People just abandon their houses and go away. I plan to leave if I have a chance. Find a better job. These people live in cities, towns, and villages, in what became known as areas affected by the Chernobyl accident. These affected areas stretch over parts of territories of the Ukraine, Yellow Russia, and the Russian Federation. All in all, there are some 2,700 settlements with a combined population of about 1 million people. The ill-fated fourth unit of the Chernobyl nuclear power plant has been sealed by a sarcophagus. But nonetheless, many concerns and fears exist about immediate and long-term effects of Chernobyl fallout. In October 1989, the Soviet government asked the International Atomic Energy Agency to carry out an assessment of the radiological consequences in the Soviet Union of the Chernobyl accident, as well as an assessment of the protective measures they had taken to protect the population. The response was an international effort carried out by almost 200 scientists from 24 countries. The geography of the project covered affected areas in the three Soviet republics. In the years since the accident, a considerable amount of data on environmental contamination had been collected. And this data served to determine exact locations for the fieldwork. The job of the experts here, as in many other locations, was to measure air and soil contamination. The necessary instrumentation was brought along. Delicate instruments did most of the job and did it well. But there was some muscle work, too. In order to form a representative picture of overall contamination, the number of soil and grass samples ran into hundreds. The grass, sealed in plastic bags together with other samples, traveled to laboratories in various countries for scrupulous analysis. The experts went to selected locations, but they were not restricted in their movement or work. They carried on their activities, as required by the project, and were willingly admitted into public places and individual homes. Moreover, as in this kindergarten, they were specifically asked to take measurements. Savici, some 40 kilometers from the Chernobyl nuclear power plant. Quite high contamination levels were expected in this village. But a visitor to Savici is surprised to see that in spite of radiation, life still goes on here. The villagers showed keen interest in the fieldwork done by the experts. The local people had been relocated soon after the accident, but the majority had come back disregarding the official ban. It seems that nothing could waver the determination of these people to stick to their traditional way of life and their homes. As for the project, one of the main tasks was to determine safe living conditions. This is a so-called APERM type of radiation measurement, which should stay in this house for one month or two months to be picked up again and from the different radiation, which has been measured by this dose meter, which is exactly the same, but packed in a plastic and sealed up here to be proof against the radon which comes from the ground. And this will measure all the radiation which is here in this room. The stops at villages designated for the survey lasted longer than strictly required for the measurements. The human dimension was always in evidence. Time for a quick polaroid photo before the group takes its leave and moves on to another location. Facts do not always lie on the surface. Sediment samples from a lake close to the evacuations zone provide valuable material for analysis. Water flows, time passes, and things change. But this brown slice of sediment from the bottom of the lake possesses a memory that can be probed. In the late stages of the project, radiation meters were collected from locations where they were deposited by previous teams. Some 2,000 measurements of external gamma dose rates at outdoor and indoor locations were taken. This particular task has been carried out to meet one of the goals of the project, to verify the available data on environmental contamination. The locations were private homes, schools, and kindergartens. Since the project did not undertake to duplicate all of the efforts of the Soviet authorities, the measurements taken have served as key input parameters to corroborate methodology used in the Soviet analysis. Is that a real thing? It's true. It's true. It's a real thing. Your house is clean. It's not clean. It's not clean. Not all of the houses in the affected areas are that safe. The evacuation zone has villages and settlements abandoned immediately after the accident because of high radiation levels. The deserted houses are slowly decaying, and there's little chance that people would ever come back to these settlements. One way to quantify the radiological situation in the affected areas is by contamination maps. This one shows contamination in cesium 137. Area is extremely large, stretching from the north of Kiev, running through southern and eastern provinces of Bielorussia, and then going into the south of the Russian Federation. Shortly after the accident, the highest environmental contamination was in the 30-kilometer zone shown as a circle on the map. Few accessible roads coming close to the 30-kilometer zone are left. This is the prohibited zone. Since the accident, this is as far as you can go. Fenced off by barbed wire, this zone immediately around Chernobyl will remain closed for human habitation for many years to come. Within a stone's throw from the Chernobyl nuclear power plant lies the town of Pripyat. It's a ghost town now, abandoned by its 45,000 inhabitants. Pripyat is designed to stand out in solitude until it falls down under its own weight. Relocation of people from these areas was mandated by the authorities. But rehousing population from places with lower levels of radiation remains a controversial issue. We all have the same plans. There is immediate relocation. There is a plan for relocation, but the whole point is where. There is no housing, no place to move in. The psychological pressure put on the population with the help of the press by means of incompetent and professional judgments is being felt more strongly now.  At the time of the Chernobyl accident, the prevailing winds blew to the north and west. Because of the wind factor and sporadic rainfall, the heaviest radiation effects were felt across an area between the eastern provinces of Belarus and the south of the Russian Federation. That is why teams of experts have also explored the southern parts of the Russian Federation. Here in Novia Bobovici, water samples were taken from one of the many public water wells closed down for fear of contamination. One of the goals of the project was to verify the Soviet methodology. In implementing this task, international experts had understanding and assistance from their Soviet counterparts. An Austrian expert and a local Soviet radiation officer probed the same soil, but with different tools. Teams of international experts were also able to examine work done and data accumulated by research institutions in the affected areas. For example, a visit to the Institute of Agricultural Radiology in Gomel provided a lot of evidence. I was very impressed because they collected a tremendous amount of data. They are well stored there. They are used for tables, for graphs, for maps, and above all, I was deeply impressed because they did not just only collect data. They gave also advice to the people to improve the situation. And I was deeply impressed by that improvement. If you just compare the contamination level, for instance, of pasture land or what is even more important of milk in the years 1986, 87, 89, and now you see a really great improvement, which now in most of the areas came down to background level. One of the major features of the contamination pattern, it is very uneven with wide variations in intensity. However, the numbers in this map should be taken with caution. The external limit of this area represents a contamination level that has been found in many West European cities. Therefore, it can give you a wrong picture if you look in the full contamination map. The real problem is not the contamination. The problem is the doses that people receive, radiation dose that people receive, and the health effects on these people. To calculate doses properly, information was needed on internal body contaminants. Novosibkov in the Russian Federation was one of the locations for the mobile laboratory that measured whole body radiation counts. The mobile van was provided by France. It was equipped with four whole body counters and packed with electronics, which enabled the team who worked there to produce immediate results of internal cesium contamination. Over a 10-week period, project teams used this mobile laboratory to measure internal contamination in some 10,000 people in the Ukraine, Belarusia, and the Russian Federation. The service was offered to anyone who came, and people queued up for measurements to be taken. How do they see their own health? We hear that because of the nature of our diseases, we get more chronic ailments. Children suffer. Whichever way it takes here or there, I couldn't care less.  I'm 61. In general, I feel bad. For example, I didn't feel any pain before. Now it hurts to leave my arms. I feel as if something is put over my head. Radiation is the most dangerous thing. Fear is fear, but radiation is worse. I'm afraid for the sake of little children. They told us that our doses are so small that the instrument could not pick up our radiation count. Well, I've been living here for four years, and the boys have been living for four years, but they've gone away for this summer. No, it's very, very little. For instance, if you're flying with a plane from Moscow to New York and back, if you fly back from Moscow to New York by plane, then you will receive about the same dose. You will receive the same dose. Thank you very much for your attention. Thank you very much. Thank you very much. The work plan did not try to duplicate the vast amount of work that had been done in the Soviet Union. Its job was to evaluate the data that had been accumulated for accuracy, for reliability, and to carry out independent fieldwork to substantiate the judgments that would have to be made. Project teams sought to corroborate the available data on environmental contamination. In doing so, the experts often consulted radiological maps compiled by local radiation protection authorities. The maps gave a fair picture of radiation contamination when verified through fieldwork. This is not too high here, as it would be according to the maps. It's certainly lower here than it was over there. A principal pathway of radiation exposure for humans is through consumption of contaminated foodstuffs. It was essential, therefore, to establish the uptake of radionuclides in the food chain. One of the control villages for the survey of radionuclides in the food chain was Daletta in the Ukraine. It was selected for the survey because of peculiar soil characteristics. We have a relatively low external gamma-dose rate in the area, but due to the soil characteristics, we have an increased transfer from radionuclides deposited on the soil into the plant. This results that there's no restriction necessary in terms of movement of children playing or in the area, movement of adults carrying out agricultural work, but the locally grown food can contain increased levels of radionuclides, such as cesium and strontium-90. Peculiar soil characteristics of country roads were negotiated by Volga taxicabs, a familiar means of transportation for the project teams. We carried out food sampling in two very different areas, different in respect to the radioactive contamination. One area, Daletta in the Ukraine, is known to be characterized by very high transfer factors from the environment into the food chain. The other area is serving as a control village, which means that according to the official USSR data, radioactive contamination in that area is known to be very low. We sampled locally produced milk, vegetables, bread in the area, or potatoes. These samples will be analyzed in laboratories in different parts of the world, and the outcome of this result will be used as an input parameter for those calculations to the critical group or particular segments of the population in the affected areas. One of the impressions gained during the fieldwork was that people living in the affected areas have poor nutrition. Empty shelves in shops reflect difficult social conditions presently affecting large parts of the country. The supply of clean products runs into the problem of adequate production and distribution. The question of supply and demand affects big towns and small villages equally. We found out in talking to these two ladies that there is milk produced in this town, and we got a sample from the lady in the white scarf. She was kind enough to bring us a sample to bring back for analysis. And in a quick survey here, we found that this milk is contaminated, and so we asked her if she drinks the milk, and she says no, she gets milk from Kiev. Once a week, the state provides enough milk for the people in the town to drink. However, the lady in the red scarf says that she dislikes the taste of this milk from Kiev. She won't drink it, her family doesn't drink it, she has grown children, she's not worried, and they will drink their own contaminated milk. So it's obvious in the town there's really a variation in how much contaminated milk people drink and what effect it will have on them ultimately. There have been many media reports on severe somatic effects and genetic malformations in the affected areas attributed to radiation exposure. Since these observations do not correlate with available radio epidemiological data, one of the main tasks was to clarify the clinical health situation in these regions. A typical medical team conducted thorough medical checkups. The day today is devoted to children and we are looking at two-year-old children, five-year-old children, and 10-year-old children. The reason for seeing the two-year-old children is to look at the incidents of anemia and nutritional factors. The reason for looking at the five-year-old children is that they should have been exposed to the most radioactive iodine since they would have been drinking milk at the time of the accident. And the 10-year-old children were specifically interested in their thyroid function since this is possibly an endemic goiter region or a region of thyroid abnormality before the accident. Okay, in this room, they're palpating thyroids looking for nodules as well as size of the thyroid. We are even doing it in the two-year-olds. In this particular instance, Dr. Hurley and one of our colleagues from Keev are working together. It's really turned out to be essential to have them working together in order to be able to deal especially with children in their own language and in terminology that they understand. Further on, thyroid ultrasound is being done with the help of machines brought in as part of the project instrumentation. The Soviet colleagues were also trained to work on the machine. We have again our colleagues from Keev in Moscow here helping us and working with us. The particular machine is used for measuring the size of the thyroid as well as looking for nodules and the consistency and internal architecture of the thyroid gland itself. Simultaneously, blood samples were being analyzed next door. This particular hematological analysis machine can analyze a blood sample 300 times in one minute, giving a most complete picture. The result is printed out immediately. Complete physical examination is done by Dr. Sasaki from Hiroshima, Japan. I think she has some very mild stomach problem. But by my examination, I can find any abnormalities. Dr. Stark is a pediatrician, hematologist, and oncologist. But besides that, he has qualities that make him a favorite with his little patients. Inlanda, inlanda, inlanda, inlanda, inlanda. Nicolay Nicolayevich, how are you feeling? How are you feeling? I'm fine. A few blocks away from the hospital during musical hour at a kindergarten, the children are largely unaware of the Chernobyl debate that often bewilders the adults. If they are to grow free from fear, facts about Chernobyl must be established, documented, and communicated. The overall strategy of the International Chernobyl Project was to examine the validity of the official methodologies and independently verify them through field samples and laboratory analysis. The last measurement having been taken and the last sample having been packed, the field work was completed. Science and research laboratories in many countries began to analyze the results. The findings of the project were handed over to the International Advisory Committee, which was set up to direct the project and be solely responsible for its findings. It is composed of scientists from United Nations organizations, universities, and renowned institutions worldwide. To achieve a balanced perspective on interpreting the scientific findings, the members were chosen to represent a wide spectrum of disciplines. It is chaired by Dr. Itsuzo Shigematsu, Director of the Radiation Effects Research Foundation in Hiroshima, Japan. As a result, we're fortunate to say that we have found no such serious health hazards as the ones which had been reported in the past. We have also found out that the survey results gained by the USSR were in large part consistent with our international findings. We hope that this report, presented at the International Atomic Energy Agency, will be helpful to the Soviet people and that they will continue their endeavor to maintain the health of the affected population.


Terms in our field often involve things like deficits and excesses so behavioral deficits and behavioral excesses Let's take a look. I would like to first demonstrate and speak about something a real excess Thank you So we would engage in a response to reduce that either Brad would engage in that response or I might engage in self-management to Reduce that response. So we would want to reduce a behavioral excess. However, if I wasn't speaking enough I I'm not speaking. Behavioral deficit.  Oh I will now I'm gonna talk really fast because you pull the string and I have to slow down as the string winds back in so a behavioral Deficit would be not engaging enough of a particular response. Whatever that response may be It needs to be increased in order to meet whatever criteria in your environment or the criteria you've set for yourself If you're doing this thing in a self-management And if you ever see me in the wild go ahead and pull my strings and see what happens because you haven't seen me talk quick yet you


I'm going to give some people time to, I got the deck up and if you can download it if you want to follow along, but my name is John DeWise, this is my meta-moments which is a talk about my process of learning metaprogramming, a project I worked on, the concepts I needed to learn to work on that project and just kind of how to use them, how to start hacking away. So I'm going to jump to the bottom of this slide first. I have different code snippets and we're going to move through them and so if you want to see them in their entirety and be able to go back if you go to speakerdeck.com DeWise, my last name slash meta, you can download the PDF or you can just follow along. So if you move on it's my last name slash meta. So I've been a software developer at Braintree in Chicago for two years, that's about how long I've been a dev so this was a talk about I wanted to learn metaprogramming and how that came about. My GitHub is at DeWise if you want to check me out there. Required disclaimer, the views expressed in this presentation are my own and not those of PayPal or it's affiliates like Braintree. This is my first time speaking at a tech conference so I want your feedback, my hope is I spoke slowly enough, I explained topics clearly without making us too many assumptions about what people knew, I used language that was inclusive and welcoming and most importantly that you got something out of this. I'm open to compliments or criticism so if you're willing to share please find me afterwards, I would be grateful. It's not really anonymous feedback but if you hide your name tag I can't see who you are and that's kind of like anonymous feedback so that'll work. What is metaprogramming? So to start I'm going to describe some summaries and uses of metaprogramming before going into kind of the tools you can use. I know I hate it when I start going to a talk and a few minutes in realize I'm missing some basic information and too embarrassed to leave so I just sit there and nod periodically. I've tried to briefly describe any topic I talk about in case you are pretty new to some stuff I'm sure I'll miss some spots so feel free to find me afterwards if you have more questions. So what is metaprogramming? I thought about using the Wikipedia definition but that's boring when you do that. It's long and encompasses a lot more than I'm going to talk about so I'm going to talk about some ways that I view it which are not official but especially when you're learning I think they're kind of useful. The first is writing code that writes code. This is sort of a lazy definition but the idea is that you can write code in such a way that new behavior can be added at runtime or compile time. So one example if you've ever used factory girl for creating objects and testing when you have different parameters those are actually methods that you end up getting called that aren't there at time using some of the metaprogramming tools available to you. It's also writing code with incomplete information. I'll talk about this a little more later but for example if you've ever used one of these Rails magic methods fined by column name the way that is implemented is with imperfect information and we'll explain that kind of later. Finally writing code really efficiently so if we were to take this bit of code we have a user we get all the methods on the user and look for all the methods that begin with validate and then we're going to use send which we'll talk about as a way to call those methods. So these three lines can actually call a ton of lines of code without having to know what methods we're even calling. Before we go any further I want to talk a little about the perils of metaprogramming. When I told someone I on the plane I was doing the metaprogramming talk they asked oh are you just going to tell people not to do it?  Metaprogramming can produce a lot of unexpected behavior so if you use this for example if I didn't see this call and I added a method I could be calling something that I only want to call in a very specific situation. It can be hard to test. You can be doing stuff manipulating the way the code works manipulating inheritance and ancestry that it can be sometimes hard to test without doing some really ugly stubs and mocks that are not great. It's slow if you don't know what the method cache is it stores methods that get called commonly to speed up the process and every time you add new methods you invalidate that cache. We all know what it means to invalidate a cache it's really hard to deal with. And finally metaprogramming is meta. It is clever. It often requires knowledge of the surrounding code and possibly other unseen interactions to work well and almost always clever code is the wrong code to write. It can increase the burden of other people jumping into a code base and often the more clear and readable solution even if it's going to be more lines and it's not elegant is probably the better code. That being said there are also some perks. It's efficient. So going back to that validate method I can call hundreds of methods with three lines of code. I don't need to worry if someone adds validations I know they're just going to get called. It's powerful. It can allow you to again change the behavior of a class change the way classes inherit from each other to a certain situation but not another one. You can manipulate the code base in very useful ways. I think the most important thing is it's fun which is why if you're new and someone tells you don't to not metaprogram you should metaprogram.  Ruby allows some really powerful stuff that you can do and I think the curiosity that you use to explore metaprogramming should be fed and should be something that's exciting to play with. So my final caveats I think of it it's kind of like Spider-Man with a lightsaber so if you are familiar with Spider-Man or not Uncle Ben has these words with great power comes great responsibility.  Lightsabers are fun. If you actually had one you probably would have cut off all of your limbs by now. But if you have one and you haven't cut off your limbs and you know how to use it that probably means you're a Jedi which is also pretty cool.  It's not putter despite the picture but I'm inevitably going to mispronounce my own gem throughout this so I'm just going to go with it. I'm going to show how the gem what it does and then all the metaprogramming tools I learned and then how they got used to build this gem. It's a little bit of shameless self-promotion but I think it's a lot easier to understand concepts when they're inside of an idea inside of a you know set of code as opposed to just talking about them. So putter is a puts debugging gem. If any of you don't know what puts debugging is it's the really fancy you know advanced method where you just put put statements everywhere to figure out where you are in your code and what is going on. Has anyone else written this one before? What's my arg so you can find it at github.com to wise putter and despite the fact that I have a putter in the background it rhymes with good or not gutter. So this is a little script that uses putter so we are going to grab it we have a user class we're going to make the username read writeable initialize with a number. The username is going to be user underscore whatever that number is. We're going to find two methods they're just kind of wrappers around the built-in Ruby ones uppercase and lowercase and we're going to close them. You'll see me throughout this I use a lot of semicolons instead of new lines because that way the code can be bigger so I assure you it works it's just a way to kind of write the code a little more succinctly. After that we're going to call putter.watch there's two apis watch and follow we're going to use watch here and we'll talk about both later. We'll have a user's array and then zero to four so we'll have five users we'll create them all we'll put each user into our array and then we're going to call uppercase on that user then we're going to go through and get all the even numbered users so zero two and four indexes and we're going to call lowercase. What happens is you get this and I'll do a zoomed in version on the next slide we're going to be able to see these are some snippets in the top you see that on the user class at line 15 of watch I called the new method I passed in zero and the result was a user the next one is the first instance of user which is the one I just created on line 17 I call uppercase with no args and I get user underscore zero and capitalized and then from the bottom user instance five which is actually index four on line 20 I call lowercase so what you can do with putter is you can use some integration test or some sort of test at the outside of your code you can watch a class and you can see every single place where that class is called any class method is called or any method is called on an instance of that class what file it's called in what args was called with and what the result was I use this when I wanted to understand a code base that I had never seen before and I needed to follow one path this will tell you a giant output of all the methods that gets called through that putter also has some configurations to ignore methods from active record and object or if you want to learn how active record works active record calls id and class a lot I had no idea so I added some ways to ignore that but it's kind of interesting to see all the different things that rails does under the hood you can use this to do here the topics we're going to talk about as far as the tools and then we'll use them I'll show how I use them in putter I'm not going to read these right now but we'll go through each one some are more strictly meta than others but they all can be useful and if you haven't seen them before it's kind of important to have these tools at least under your tool belt there are other ways to do meta programming there might be right ways that I'm not discussing additionally I'm probably going to lie to you because when it comes to meta programming there's a lot of edge cases some that I found and some I haven't found yet some cases where self changes depending on what method you're in it's easier just to tell you what's going to work 90 of the time I encourage you to play with it and find those edge cases for yourself but just know that meta programming is fun but dark and full of tears so first up is send sends an extremely powerful tool is one method to call them all send will invoke a method it'll call a method using a symbol or a string of the method name it also lets you call any method so if you've ever heard of ruby that there's no such thing as private methods it's because you can use send to call anything so let's take a look at kind of how that works so i'm going to be using the pry gem here which is kind of like irb just open up a random like ruby session rebel so this is using pry and ruby 231 most things if you do this will be similar i removed a couple lines where if you define a method it returns the symbol of the method name just for ease but for the most part you can follow this code along if you want to type it yourself to see what happens we'll define a method called send me it'll let us know it was sent and we'll close it up we'll create a new instance of our sender we'll send send me and we'll see that it was sent so you can see that we can just call a method using send and if that method name were a variable that we didn't know we call methods we didn't know about next is inheritance i know most people are probably familiar with inherits a truck is a type of vehicle most of our users probably inherit from active record you may have heard the is a trick so if something is a something else it inherits if it behaves like it you know will implement and depending on what language you're in those are interfaces or whatever um so because of this like any vehicle a truck can drive it has a make and model but it's a little different because it can tow a user will have save or update attributes that come from it as a part of active record okay so that part i think most people have seen before but what i didn't know about inheritance is when you use include and extend you're actually dealing with inheritance this is changing inheritance i used to think this was composition because i was i was composing modules i was adding them in there was no less than signed inherit from but that's wrong it is definitely inheritance so if i have a television that extends broadcastable or includes watchable um it's actually inheriting from those that will change the inheritance chain so we can take a look at this one too we have a parent we'll have a parent method it's gonna say i'm parenting close that we have a child uh we'll include the parent and we'll define that parent method again and we'll just call super so because it's inheritance i will call whatever my superclasses version of that method is close it create a new child which is much more complicated than just doing this but we'll call parent method on it and we'll see i'm parenting so to explore that a little more we'll get into ancestors so how the heck do you know what you're inheriting from well we can look at the ancestors the ancestors method will show the inheritance chain and the order that it happens in almost all objects inherent from object if you've ever seen that object also will mix in kernel which is where puts comes from our chomp and eval that get included in and in the end all objects inherit from basic object which we'll talk about a little later finally the last module that gets included is the first parent so we have a grandparent we have a parent we have a child we'll include the grandparent first because they came first and then the parent close that up and then we'll take a look at the ancestors so we see our child and even though we include a parent second it's the first one we see and then grandparent comes next you also see object because we inherit from that the pp object mix in is for pretty printing it's included by pri if you were using irb you would not see that uh then there's also kernel which is where we get puts and then basic object now we're going to talk about prepend again this is not necessarily a metaprogramming thing but it can be used to do some cool metaprogramming stuff prepend functions like include except it put something before itself so you know append prepend and you know javascript it can be useful for things like proxy modules because you can actually prepend a module whose methods will be called before the class that they are prepended in and we'll see that a little later so let's make a proxy we'll have a proxy method it's going to tell us it was proxied and then notice we'll call super again i apologize for the semicolons but we're going to call super on this we'll create a test class and we'll prepend proxy to find that same method letting us know that we got here because that's how you debug create a new instance of our test and we'll call proxy we'll see first that we get proxied from the method in our proxy then we get to get there so as a result we can create things that interrupt methods and do stuff before they get called so if we were looking at the ancestors of our test class we see that proxy is now actually sitting in front of the test class itself so it's a really powerful thing that you can do to be able to stop methods interrupt them modify them as they're in flight next up is method dispatch so what is that method dispatch is the way that ruby determines what method to call there are some really great diagrams with this i didn't want to steal them so if you google method dispatch of ruby you'll see them but the idea is it'll search the ancestry train going up that list of ancestors and the first one that implements the method it will return that method so we'll take a look at how ancestry works i was trying to think of an example of something where the location of something changes and i thought a good example would be figuring out who owns my student loans so if you don't know sally may they're now called naviant so we'll have a naviant loan and a sally may loan and sally may will include the naviant loan close that up well the u.s. government loan because i think they had it at one point i don't know they might still to find an owner method they'll let us know that they own the loans we'll create a loan class which includes the u.s. government loan first and then sally may but notice not explicitly including naviant we'll close that up so now we're going to take a look at when we call this owner method and change it what happens we create a new loan have our instance we call owner and we see the message that the u.s. government loan had will create a naviant loan to find owner and if you didn't know this you can actually reopen up modules and classes add methods to them at any point rails will do stuff if you've ever used the present method you can open up the nil class that or the true class or the false class or number classes so you can add your own methods to anything this will say your loans have been sold and we'll call owner on it now and now our loans have been sold just by adding that method to the naviant loan so now we'll take a look at the ancestors so we see first is the loan then the sally may loan because we included that first but that also we include then the naviant loan because it was included by sally may which will be included before the u.s. government loan so the more often that you have things included that actually changes your ancestry train can change it a lot because you're including everything that gets included by everything else so what does this have to do with metaprogramming none of this really has been metaprogramming so far i promise we're getting there but you know knowledge is power so now we're gonna get on to some of the cooler stuff that you can actually do starting to use these tools method missing method missing if you haven't seen it before is defined like this it is called when a method cannot be found so if you've ever had a method not found there it typically means that method missing was not defined anywhere in that method dispatch chain so remember those ancestors the first method missing that is defined in the first ancestor that it finds it in will be what is used it has access to the method that was called the args passed into it and any blocks that may have been passed in if you haven't seen the ampersand block symbol uh root any ruby method can actually implement this that you can pass a block to any method you don't have to have it so we'll take a look at how to use this we have a parent we'll define method missing on the parent which we're going to ignore the block for now and when we do that we'll put the method and the arguments that we get we have a child which will include the parent then we'll do child new and we'll call do stuff and we'll pass and things notice we didn't define do stuff anywhere but what we get is method do stuff and the args are and things um and you'll notice that we get an array because that star args if you haven't seen it before splat args is a way to kind of close up any unknown number of arguments so if we would have had 10 arguments or three it you know combines them all into this one array which is why we see an array of the two arguments that we passed so this means anytime a method doesn't exist we can change behavior we can make it exist and we'll see shortly we can write code with incomplete information so a more complicated example uh you may have all seen again active record defined by a magic methods we're going to make our own version we're going to call it lazy record because it's not going to do much we'll have a method missing i use m this time just because i needed screen real estate if the method name matches find by underscore we're going to take the trait all this does is whatever comes after find by underscore it's going to grab that thing so if we did find by name it would be name find by username it would be username etc and then we're going to call self dot where and this i'm going to pretend is the same as an active record call we can call where with kind of some pseudo sequel and we're going to pass whatever the first argument passed to the method missing colors now we don't have where to find so we're going to make a fake where it's going to tell us it's doing a database lookup and regardless of what we send it's going to return to make emails and close that up so now we're going to create a user we're going to use this we have a user that inherits from lazy record we're going to find by name mickey so we're doing our database lookup now i didn't put this out there but this is basically what we do if we have this where method that can do a sequel search it's going to do something like that and it's going to return mickey mouse again to be fair if we did find by zip code we would also get mickey mouse so this isn't very helpful but if you were backed up by a database or if in any case you wanted to respond to methods that were somewhat dynamic or helpful you can do that i think active record has since deprecated the find by magic and there's actually one now find by method that takes arguments but you still may have seen this before now we're going to talk about define method we're starting to see some of the more powerful things we can do so in addition to responding to methods that don't exist we can create methods that we want to exist explicitly whenever we want we use define method it's a way to define a method with via another method so you don't need to use the def command you can actually do not even use the def command this can be also used in classes you can create methods whenever you want like on method missing you can create a new method and ultimately this takes a method name and a block and the block is the body of that method so we'll have a define class we'll define method missing and we'll say that if that block was passed in that means someone wants a custom method so we'll define it we'll do self.class.send and the reason we do self.class is because methods can't actually do they can but for this purpose they can't be defined on an instance so we're going to define it on the class and we're going to send define method it's a private method so we have to use send the method and the block that's passed in if there is no block so they didn't pass this a method body we'll define just a hello method self.class.send we'll call define method again and we're going to pass our own block so that's what the do is if you aren't familiar with blocks or I mean you've all we've all used them each do but if you haven't been familiar with how they work it's a great use of a weekend to kind of dive into how they can be passed around and you know they're like callbacks and javascript was something that kind of helped me uh that's not really an accurate definition totally but I encourage you to explore it more we're going to close everything up we'll create a new instance of define we're going to call world we'll see that we didn't pass a block so we're just defining a hello method and we'll call it again but now instead of defining it we actually have a method that's going to say hello world if I called it again it would the same thing would happen if we pass a block in we're going to revolt and pass an argument it's going to let us know it doesn't want to say hello whatever so close that up now it's going to tell us we're defining a custom method now if I call it again notice I'm not passing a block this time because I don't have a method body but I'm going to pass an argument it'll say I don't want to say hello world so you can actually define new methods with blocks that are passed in by the user you can define new methods with things that you want um being able to define new methods when methods don't exist or for other reasons gives you a lot of flexibility basic object basic object is the source of all objects it only has a handful of instance methods which makes it very useful for metaprogramming here are all the instance methods that exist on basic object all the public ones three of them begin with double underscore they're you know kind of private internal methods we're going to take a look in a little bit at instance evon exec but you see that this is mostly a blank slate almost to work with it's also the source of the method magical method missing as well as initialize those are private instance methods on basic object object has about six 56 methods or 63 if you're in pry and then basic object has I think was nine so it kind of tells you like how small and uh paired down this is versus the normal object you interact with singleton classes a singleton class might also be called a metaclass it might also be called an eigenclass to my knowledge there's not universal agreement on this there might be but people like to argue about what this is called so i'm gonna call it a singleton class the way to view it is it's a class that it itself is an object so it's not an instance of a class in it it is the instance of the class it's not like user.new so a class method is actually just an instance method on the singleton class so when you have a class user and you have an all method that gets all the users you have user.all that is actually a class method but it's an instance method on the singleton class um this is one of the harder concepts at least for me it was a little bit harder to grab but it's the idea again that that class is its own instance and we'll take a little bit of a look at it we have a greeter class says hello you can do self.hello which is i think what mostly we will see for class methods you can also define it on the class and do greeter.high and if you've ever seen this before this is actually a way to say i want to open up the singleton class and i'm going to put methods on it so i'm going to define yo but notice i don't need self and i don't need the class name close that up call hello hi and yo and if we look at the singleton methods on greeter we'll see the three ones that we defined so these are all again all class methods but they're methods defined on the single methods defined instance methods on the singleton class another way to look at it would be if we look at all the methods which returns class methods on greeter and we subtract away all the methods on object we'll see this or take greeter we get the singleton class and greeter and the instance methods on that and get rid of all the class methods on object again we see this so when i said you can't define a method of an instance you can't but you can because you can actually get a singleton class on an instance instances can have their own singleton class which is kind of a copy of the parent class that they have but a copy that can be modified and when you modify it it only affects that instance so we have a thing look at the singleton class a thing instead of saying thing like now we see kind of the ruby hashtag and then in carrots if we look at an instance of thing you've seen this before too now if we look at the singleton class of that instance we'll actually see like a it's not on a string but a you know line that looks very similar to a combination of those two and if we look at the ancestors of that singleton class on the instance we'll see that that wasn't supposed to that thing object and all through basic object um instance eval so this is the last thing we're going to talk about before we get into how putters put together there's also instance exact which we'll talk about the difference shortly this is a way to eval code in an instance or a class kind of if you've ever heard of ruby eval or don't use ruby eval it's a way to kind of evaluate code um one thing i that i apologize it's not a method eval does not take a method it actually takes an object it does not take an object an exec does so we'll take a look at whether or not you use which and why you might pass an object in so create a spy class new it up and we'll store some secrets the secret apple pie recipe inside the spy to create a new instance of spy and we get those secrets see we have an undefined method secrets because there's no public getter for that we could use this really ugly method which i would not recommend using but you can do instance variable get to see the instance variable when we see our secrets but there's another way to do it we knew up a new spy and we can do instance eval and put at secrets we see our apple pie recipe because this code is actually evaluated inside that instance and inside that instance at secrets is a method that you have you know a special way to get that instance variable so this is a little contrived so let's look at maybe a better example which was also contrived but still useful we have a neo class kiana will be our instance of neo so we have this instance now we're going to do a class exec so instead of eval exec and we're going to pass something in in this case we're passing just a method but you could actually pass an object full of data to do various things with and we're going to give an argument to the block which is that method we passed in or the argument we passed in we're going to define a method which is going to be trained in this case kiana is going to let us know he knows kung fu close it up we call it kiana dot train kano say i know kung fu so we will actually add a method to the class using the defined method and add behavior arm with this ability being able to pass the variables user input we can modify a class whose name we don't know add a method whose name we don't know and if we pass around a block our proc we can define a method body that we don't know so it's some pretty powerful stuff if you build stuff in such a way that you can take advantage to it so i'm going to show you what i did with putter to use all these tools to kind of create my puts debugging gem so first we're going to look at the method follow so follow takes an instance it can also take a class but more commonly you'll use an instance and what it does is it creates this putter follower object which inherits from basic objects so this follower has almost no methods on it and we store the user object the instance uh as an instance variable so we have this follower that is the result of putter.follow uh we saw that and what we'll do is we'll create a new proxy we're going to take our instance and we are going to get the singleton class of the instance which lets you again define methods just on that instance and we're going to prepend the proxy so we end up with something that kind of looks like this we have a follower object the wraps the user object that has a proxy that sits in front of it so we're going to call follower which is our wrapped instance i want to say do something with stuff the first thing that's going to happen is we're going to hit the method missing call in the follower object again it's a basic object so it has nothing on it unless you were to call instanceeval or exec you're going to hit this and on that method missing we're going to determine first if we should add the method to the proxy now we could have skipped this step but putter has some configuration where you can blacklist or whitelist methods or ignore methods from object or active record to kind of create down place of noise so that's why we do that but you could skip this part so we have our add method then what we're going to do is we have this data object and we're going to take that proxy and we're going to do instance exec we're going to pass that data in that data has information about how to print it has information about the method that we're calling we're going to define a method with the method that's stored in data then what we're going to do is we're going to call result equals super so what we're going to do in this case since it's a pre-pended proxy it's going to call super which is whatever method was on that object the method we were trying to call to begin with the only catch is we're going to store the result then we're going to put log info which you can actually configure with a proc you can configure it to print anything and it includes the line number it figures out where the caller is coming from and then we'll return the result so as if what you called was returning the result anyway then if we have already added the method you might hit the else either way what we end up doing then is we called to do something with stuff and then the user object and then as far as your code is concerned it got the same thing back the only difference was it printed out to the screen information about what just happened so the other side of putter is watch so with watch we have this watcher class which actually holds kind of a singleton-esque registry where the key is the singleton class of a class and the value is that data object full of methods and stuff and we'll have a user class so we're going to say putter watch the user and then what happens is this we open up the singleton class of user and we're going to prepend an instance follower describe that in a second and the result of this watcher build proxy now because we opened up that class if you see the self there that self is referring to the singleton class of user so we're now defining things on the singleton class so we can first build this instance follower normally when you create a method that allows you to change initialize or that allows you to new up an object we use initialize because new actually deals with memory allocation so what we're going to do is override new kind of we're still going to call super new because I don't want to mess with the memory allocation but the object that comes back from that we're going to store in an array of objects so we know how many are being created and then we're going to call putter.follow on that object so that object that now gets created is actually a followed object that is printing along and we've set a label to be the instance number of whatever that array size is so now we're both getting our class methods and instance methods followed putter watcher is going to build a proxy with the singleton class of user which is what self is so build proxy looks almost identical to what we did before the only difference is we're going to call proxy methods on user which is a method that putter adds that again checks the methods that are whitelisted and blacklisted and it checks the existing class methods on the user it does not if you were to add methods to user at runtime it would not get those there are hooks in Ruby you can do when a method's added if you want to add a pr to a putter to take care of that you're welcome to and then we do the same stuff we define a method we get a result of the super class and we put the info and return it so that looks something like this we have this object which has a proxy with for the methods that are proxied an instance follower and a user class so we user do something which in this case is a class method he's going to call do something on the proxy in this case it won't do anything with the instance and then it'll call do something on the user user.new is going to actually return this and let us know that we called that new method so somewhere of what this does we use method missing to call send with instance eval inside of define method we also prepend a proxy that calls super but puts a bunch of information and we're also able to override new which follows all instances so what do we do with all this stuff metaprogramming in ways like learning another language another programming language so if you're out like me you'll go learn elixir or node or haskell or whatever and then you sit there thinking I really want to make something but what I made this there's a lot of power and cool stuff that you can do with metaprogramming so you can contribute to things like rails or factory girl or you can contribute to putter it's my first open source project so I will be very nice because I don't really know what I'm doing so if you're looking for something to get into but you're afraid of people being mean I'm just as cool as PRs are welcome so I made this what will you make here's some resources I used there's an article by Thoughtbot called writing a DSL in ruby it's kind of a slim down version of how factory girl is implemented which taught me a lot about how metaprogramming can work ruby under microscope is a great book which has been mentioned at a couple other talks it talks about how ruby is implemented kind of at the c level at the vm the first three chapters if you are like me we're a little rough because they did talk about the vm and some of the c implementation which was over my head so if you get to that point you're like I don't know if this is for me you can skip the first three chapters read about the other stuff and then when you kind of got you know more experience under your feet go back and read them because they're really great and metaprogramming ruby 2 is just a book about metaprogramming and it's also fantastic it goes over a lot of this in more detail it's really useful here are all the photos I used thank you flicker and finally hopefully you have some tools to start meta hacking away I'll ask for questions I'll probably do a couple and then if anybody has questions I'll also just kind of stay up here if you don't want to ask in front of a crowd otherwise have a great RubyConf are there any questions yeah it difference between instance exec and instance eval right here you see instance exec takes this data object in so instance exec can take an object or it takes really just an argument which you could then use to load up with a bunch of data instance eval doesn't you wouldn't be able to pass anything into instance eval so it's a way to inject something from the outside world from the outside environment into that environment where you're eval is the singleton class related to the design pattern of singletons not really a singleton design pattern would be if you have one object and every time you hit new it always returns the same object wherever that's called kind of the idea that there's just this one version of that object that's also a very lazy definition of singleton design pattern but it's a way to just kind of guarantee that if I'm using a registry or a store it's the same everywhere the singleton class is not really related to that it's the idea of just that class has an object so I'm gonna stop now if anybody wants to come up and ask questions happy to take that otherwise have a great day thanks


Hi everybody, Joe for jaskiescasebreaks.com with 2019 Panini Prism Football Hobby Pack Break number six Three different dice rolls happening here. First of all, we're going to give away four spots within the pack break itself Second dice roll will be the break third dice roll are giving away those the final seven spots in 2013 crown ral football That's coming up in the in the next video Big thanks to this group here for making it happen Let's roll it and randomize it five into five ten the hard way so top four after ten one two Three and tenth and final time top four Mike Chris Michael and Mike Three Michaels and a Chris Extra spots for you and everybody on that list right there Also has a shot the break credit promo tonight Because this filler pack is part of that promo All right now let's randomize you names and teams randomize those names and teams four and a one five times one two three four and a one fifth and final time four and a one five times for the teams one two three Four and a one fifth and final time All right, here's the first half of the list right here And the second half the list right down there Thanks everybody for Making this happen. It's alphabetized by team and let's print and rip. There's an AJ green 169 out of 199 wave So nothing too crazy there. This AJ green bangles edition will go to Michael Michael Robinson But who's gonna win those final 2013 crown royale spots. Let's gather everyone's names for the third and final time top seven after two Snake eyes easy Left eye right eye So from eight on down it's gonna be Sorry Scott it's gonna be sad times From eight down to 32. Thanks everyone for giving this a shot though But happy times for the top seven you're in the next break We'll see in the next round Scott Cooper is in Coop again Terry Terry Matthew Coop and Michael Robinson Scott Cooper with three of the four spots three of the seven spots Terry got two Matthew and Michael in with one each after two times Thanks everybody. I'll see you in the next video for that break Jasper's case race.com


Jara, are you there? It's got me on mute. I don't think Wong is the play today. I think we watch this and see how it acts. It sets up. We'll do it if it doesn't. We won't. It's got to hold, break, under, and drop, and fall off a cliff almost immediately down to 32. And if that happens, great. If it doesn't, I don't think we're doing anything today, people. And we've had a very strong week. We will talk about Facebook today. I think we'll have time and I think that's just a good chart to review. We could have actually day-traded that yesterday, which is funny. Uber. A little wily. Gosh, maybe we'll just do BABA. Really wanted to do that other one instead. Nope. Nope. Not going to do it. All right. Plan of action switched around now here to BABA. Forget the Uber. It's going to be a mess if it even goes. This is going to be... I'm not going to be aggressive on this. I'm going to do 99 by 90. 99 by 90. And it's 256.99. Short. Let's put this top at 20. 99 by 20. 99 by 20. If this hits, which it didn't hit yet. 99 by 20. I know this is going to roll over today. Let's see if it does right here. 99 by 20 is still valid. I hope this goes if it doesn't because I don't like anything else. 99 by 20. You're putting your time to figure out your sizing and everything else here. It's not hit yet. I know this is going to roll over today. 99 by 20. 99 by 20. 99 by 20. Do it. Do it right now. It's going to roll over and get the stuff in at 20. Here it goes. It's going to break 257. Just do it if you want to do it. This is going to roll over and we're giving it plenty of room. If you want to wait till it breaks fine. So yeah, it's got to be that. 250.820 is the stop. 250.820, you could do it right in here or you could wait till it breaks 257 if you just want to be safe. But I'm in it. I think it looks good. Now all of a sudden the spreads wind up. But I think we're really fine. I think we're really fine. I wanted to give it enough. I don't think 15 more cents is going to matter. Put it at 258.35. 258.35 if you're in it. And if you didn't do it, then you just wait until it breaks through 257, which is going to do. This is going to roll over. This is really, really super weak. So you can do it right here or you could wait for 257 or you could wait for the break of that. But either way stops 258.35 new stop. And I don't think we're going to get a better entry in this quite frankly at all. So targets 256.255. Here. Wow. See I took that before it really triggered because I thought it was going to do that and it just did it. I thought it was going to break hard. Did everybody get it? Which we don't always jump the gun. Watch 256.256.16. We haven't traded this in a hundred years. And I think we're fine where I put this stop. Yeah, Jackie's bringing up an interesting question, but it's usually not these ones. Here we go. I can't pay attention right now. We'll talk what we're done. Here. Under 256. Here we go. It's going to break 256. That we'll talk about Whatchamacallit. We'll talk about Facebook. We'll talk about Apple. Apple was a great trade. We had it so early though that I think we would have made a heck of a lot more. But again, I didn't, it could have gone Monday there. It almost did. It's like looking back. I'm like, gosh, this should be worth so much more. Here. 256. But it was a nice trade. That pricing of that option made no sense to me yesterday whatsoever at all. Should have been like three times the amount it was worth to be. Yeah. 256. It just basically went down there. 256.06. You could have just scouted out of that if you want. Are you in it? For the next more drop, bigger, bigger, bigger. 936. These are not the ones that open late, to be honest with you. But it did kind of look like that. You're right. I was thinking the same thing. But the reality is that it's usually not this market that opens late. So here we got to pay attention now. I'm sorry. This is just moving way too fast. Is everybody in it? You had six minutes to take this, or five minutes to take it. You had a long time to take it. Got it. If you got filled on that break, as long as you got the stop at the right place in your sized right, you're up in this. If you oversize yourself, take some out. If you got filled late and you oversized, take some out. You're up in the train. Put the stop pick in the right. Here. Here. Here. Sorry. We'll talk later. Oh my gosh. What another great call. I just, it's, oh, did we break 50? I saw Facebook. I thought to myself, gosh darn it. There's nobody better than me when I'm at my best. And I wish that I was perfect every single second I was breathing, but I'm a human being. And sometimes things happen and you get distracted and whatever. But it's like at my best, there is nobody better than me. Nobody.  I don't think any single solitaire person saved that trade, stayed with that train. I was the only one that believed in that train. If you stayed with it, email me right now or chat in the room. I think everyone killed it. And I said, this is fabulous. And no one believed me. Ask where the stop is when the trade is over. It break 255. It's gonna break 255. I think that was a beautiful exit, but it will break 255. And I did call the option. Here it goes. It's gonna break 255. If you're still in it, there it did. It just did it. Just did it. Just did it. Very good. All right, Dan. Dan, if did you do this trade? If you did the trade and you didn't know the stop in, you need to discuss this with me. Because a lot of days, you're asking where it's a stop way after the trade's gone. You either A, aren't doing them. You're just watching, which is fine. Or you're not sizing yourself. I'm concerned. Here. Is anyone still in this? Again, it could be in the option. Here, let's go over it. I'm not doing anything else today. And you know what? And for the put I called 250, 252, 250. I don't know. Maybe we should just get out of this. One more push in here, even the option. Just call it a weekend.


When they walked in, I was like, wow, okay, I had these two people and I'm like, what do I do with this? There's this woman who, you know, her joints, her knees or elbows are really swollen. She said she couldn't use them and then I have this guy, two men actually that were very fit, but I think high. When I moved from New York City to Venice and I made some calls to the shelters in and around the west side and everyone was just really excited and would love Debbie Yoga programs. So I got volunteer yoga instructors and they come into the shelters one hour a week and they teach a class. I just feel so ready to give more because I feel like I've received so much and it's just that cycle and it really will, I hope it never ends. New instructors, there's a thing that they do usually when they're just beginning to teach, it's called SAVA and it's like giving back. And in the last six years we've had, I guess, over 20 weekly classes started and over 200 clients and people seem to really love it. Just being paid attention to for that hour and providing them the time just to really kind of go inside and be calm and be still and not be stressed out about, you know, where they're going to get their next meal or where they're going to sleep that night, I really personally saw, you know, the transformation it had with them. It's just been so incredible working with this fun group of guys.  Like we all start meditating, we'll start breathing. It's just sweet, it's human connection, but it's also teaching them their own human connection. I came into this thing with anger issues and I've been treated with therapy. This gives me real physical help in order to maintain that tranquility. When there's 48,000 people experiencing homelessness and there's not 48,000 shelter beds, I can understand our clients losing hope. So PATH is one of the largest homeless service providers in the state of California and our mission is to end homelessness for families, individuals and communities throughout the state of California. When I became the volunteer coordinator here, Alma Yoga was really one of the first projects that I wanted to expand. I got a sense of these people who don't really have homes, like, you know, they have temporary housing and how what a great service would be to teach them tools that they could actually do themselves to find sort of the home within their own self, no matter where they're living at the moment. I'm Axel Twist. I had gotten hit by a car. When I first started off I was walking like Frankenstein, you know, the monster. A couple months I was walking normal. More than anything, these people need someone to care about them and to be inspired and with that strength behind them they are able to make moves.