00:00:09.040
all right good morning everyone oh
00:00:14.240
yeah uh let me start saying that is a true honor uh to be opening this
00:00:19.720
conference uh you may you may recall that when um the the city of TLA was uh
00:00:27.599
selected to host uh this year uko uh you know um there was some UNC uncertainty
00:00:34.840
right because uh how how do you reach that City you know so uh I've been in
00:00:40.559
contact with with Mohamed for some months and they have worked so hard to
00:00:47.000
make this uh possible they moved to saho they have put together this amazing
00:00:53.559
lineup so I would like to ask you for a round of applause for the organization please
00:01:15.759
a bunch of of talks about zyber over the years the first you know bch we we could
00:01:22.400
say of talks uh kind of presented the the project you know what's the reason
00:01:27.640
for it and you know uh talk a little bit about the project that was RA com 2018
00:01:33.280
for instance uh I I I had the honor to give the opening keynote of rails com in
00:01:41.119
Portland 2022 in this one I talked a little bit about the history of the project some
00:01:47.680
technical difficulties that that uh we had the beginning uh some people that
00:01:53.439
help it uh with them and other stuff like that and lately I've been doing
00:02:01.000
um talks yeah that's friendly be please talk with Adrian it's going to
00:02:08.920
be next week right or yeah next week friendly we awesome awesome conference man
00:02:14.840
so uh the the last the last talks have been explaining how zyber works okay uh
00:02:22.720
because I like that people understand what is what it is doing on your behalf rather than having you know a black box
00:02:29.360
unless at least if you are interested in understanding that all right so how does
00:02:34.640
it work right but for uko uh I've prepared a brand new talk uh with a
00:02:40.680
different perspective so I would like to talk about about uh stuff related to
00:02:47.040
software development let let's say that way uh with things you know uh
00:02:53.000
gravitating towards zy or using zy as an example for things that's more or less
00:02:59.200
uh the AIM name of this talk and this is what the the things that we we are going
00:03:04.280
to talk about first I am going to do an overview of the project then uh I'm
00:03:09.560
going to talk about method signatures in Ruby um some remarks related to API
00:03:16.040
design with some humble examples from the library I would like to discuss private
00:03:22.280
interfaces in Ruby as well and then I'm going to talk a little bit about software
00:03:28.480
errors and there's a final section with some future work that is in the Horizon
00:03:34.200
all right all right let's start so um uh for those of you that may not
00:03:40.879
know what is zyber uh zyber is a is a ruby gem that provides these main
00:03:48.000
features uh to any Ruby project as long as it satisfies some uh conventions in
00:03:54.280
the file system it is the library that nowadays rails uses to provide these
00:04:00.680
features all right so the main one is autoloading autoloading means that you can use your code without using requires
00:04:09.439
basically now having autoloading in place then you are able to decide when
00:04:16.040
do you want to load your code it can be on demand lazily or it can be eagerly
00:04:22.479
right so up front it is important to understand that in order to eager load a project you
00:04:29.160
need to have have autoloading in place why because when you eer load um a
00:04:35.199
file maybe at the top level or within a class body or something you have an include of a mixing and if that mixing
00:04:42.000
was not already eager loaded then AOL loading triggers loads the miine and
00:04:47.160
your eager loading continues so it is like inter all right indeed um eager
00:04:53.479
loading is internally implemented as a recursive autoloading is not a recursive required for consist
00:05:01.120
reasons um finally reloading is the ability to uh edit your code and have
00:05:06.320
your changes refreshed basically all right there's more features in zyber
00:05:12.000
okay uh but these are the main ones so which were the the motivations
00:05:19.720
for this project so race has been able to autoload since the beginning okay but
00:05:25.800
that autoloading has uh fundamental limitations technique had fundamental limitations it was based on on a call
00:05:34.440
bat called cons missing okay um in other talks that are more technical I I do an
00:05:41.960
introduction of some concept related to constants in Ruby and look up algorithms
00:05:47.120
and that and that kind of thing but in this one we are not going to to see them all right uh sufficient is to say that
00:05:54.880
uh cons missing uh lacks important information information
00:06:00.199
about the context in order to be able to emulate the look up uh of constants that
00:06:06.039
kby does for instance it doesn't know what is the nesting the nesting is an
00:06:12.520
very important information that you have to have it doesn't know whether the constant was missed in a relative or
00:06:19.120
qualified setting and that that's very important because in one case you have
00:06:24.599
one algorithm and the other case you have a different algorithm you don't have that
00:06:30.360
information uh and we could think well perhaps uh Ruby could modify cons
00:06:35.919
missing to receive in addition to the constant that was missing that context
00:06:41.720
information well even then uh it couldn't be enough because cons missing
00:06:47.319
in the lookup algorithm is the last step is is like a fullback all right so if
00:06:54.000
you have uh a constant with the same name in different name spaces
00:07:00.680
and when you refer to that constant if everything was in memory you could hit a most specific um you know
00:07:08.840
one but in a lazy setting that is not yet AOL loaded and the lookup algorithm
00:07:15.240
is able to find the other one well Ruby could resolve the constant so cons
00:07:21.680
missing is not even going to be called right so fundamentally the technique was
00:07:27.319
useful and it was the only one that we had for many years but it was it was a source of
00:07:34.479
headaches and of you know of bad experience basically you at sometimes
00:07:40.919
you you know your code just didn't work as you expected um so my main trigger was to
00:07:49.000
fix this then another one is to automate ker
00:07:54.639
require and that is why I thought about zyber as an external gem so zyber is not
00:08:00.599
part of rails it's an external gem as I said in order to address this for arbitr
00:08:07.720
Ruby projects here two main remarks uh the first one is that require
00:08:15.199
as we all know has a global side effect okay so when you require something that code is evaluated in the context of The
00:08:22.800
Interpreter and constants are Global and you know and everything is global all right so what what what
00:08:29.639
happens in practice is that it is hard in a non-trivial rubby code
00:08:35.839
base to have dependencies on your source code maybe your source code maybe you
00:08:41.560
have a file with 200 lines you know it is hard in practice to have dependencies
00:08:47.640
on that on those 200 lines and systematically get your requires correct
00:08:54.279
eventually you're going to forget some and I know that firsthand because I have
00:08:59.480
spent countless of hours making sure that blank question mark was available
00:09:05.200
in the places within the rail cope base that use class uh blank question
00:09:11.360
mark now what happens in practice that perhaps your code Works perhaps it works
00:09:17.120
in the test Suite perhaps it works in production because by pure lack some
00:09:24.760
other code in your application happened to load the dependency so when you hit
00:09:30.560
that place the code works because of the global S
00:09:36.920
effect however that's brutal okay at some point you're going to have a Cod path that does not go through that thing
00:09:45.240
and hits your file and you get an error maybe in
00:09:50.720
production the other one is that in my experience uh for any you know medium-size Ruby Library getting the
00:09:57.880
requires well or organized is kind of hard I think by that I mean uh your your
00:10:06.320
file has to require the dependency somehow now I am in this part of the
00:10:11.800
project and I need that other file in a in an different part of the project and
00:10:17.440
the question is can I issue a require for that file directly sometimes that question is not
00:10:24.000
easy to answer because maybe you have to load before a name is space uh how to
00:10:32.000
organize this in a uniform way and in a predictable way in my experience is hard
00:10:37.800
so zyber addresses these two things and you don't have to think about them
00:10:43.279
anymore you can read any code any time the dependencies are going to be
00:10:48.399
resolved for you automatically and yeah everything is
00:10:54.519
going to work you can hit any constant path no matter how deep in your project there directly you don't have to worry
00:11:00.639
about that it's going to work those were the main two drivers behind this project
00:11:07.360
some Milestones of the library uh first first stable release was in at the
00:11:13.040
beginning of 2019 uh Shopify migrated while this thing was still in beta uh rail six had
00:11:21.600
not shipped and that was instrumental for for the project uh Jean bosier uh
00:11:29.399
championed that from the Shopify uh site and I I have phun
00:11:35.120
memories from those days they were very intense and and it was extremely good because we were able to polish some epis
00:11:43.279
we were able to improve the performance of the library and he G it gave me
00:11:49.079
confidence to ship this with rail six which happened later in AUST nice days um then GitHub soon also
00:11:58.920
migrated ated to zyu uh for those of you that may be new
00:12:04.360
to Ruby Shopify is probably the largest ra application in the world so migrating
00:12:11.600
Shopify to zyber while being in beta um I mean this was like you
00:12:19.920
couldn't have a best test than this one and then uh this GitHub migrating is
00:12:25.320
also like a confirmation like yes uh we have solution for these
00:12:31.600
problems finally classic we maintained classic for two versions rail 6.0 and
00:12:37.920
and 6.1 and the reason for that was to easy migration so uh 60 and 6 one
00:12:45.639
shipped with both autoloaders the classic one and the new one and the the
00:12:51.079
intention was to give pce of mind to users of rails so you could you could
00:12:56.279
have a rails 5 application upgrade to rails 6 and still work with the previous autoloader that maybe is not perfect but
00:13:03.160
that is the one that is working in your application okay so not not a drastic
00:13:08.279
thing you can you know upgrade and then perhaps later you know do you do a task force and say okay now we are going to
00:13:16.160
migrate uh the the autoloader all right some statistics
00:13:23.240
there have been about 50 releases of the library it's being used nowadays by
00:13:29.160
about 600 gems and maybe you do not even notice
00:13:35.519
that some of your dependencies may be using zyber because one of the design goals of of the library is to be
00:13:42.160
transparent so uh something that I wanted to achieve was that you open your
00:13:48.120
project and and your project is a normal Ruby project there's nothing special there's there's not there's no
00:13:55.399
trace of zyber in your source code your source code is your source code and looks normal right so not even client
00:14:03.079
code of the libraries need to know that the library internally uses cyberg that's that's private that's how
00:14:09.360
you how you load your code is your thing it's not even public okay the the the
00:14:14.880
client code you may document in order to use my library uh you have to require the entry point which is the standard
00:14:21.079
thing to do and that's that's it you do not you do you do not tell the user that you are using direct internally because
00:14:28.120
of transparency um almost half a million daily downloads
00:14:34.560
nowadays for a total of uh 400 million uh total loads over these five
00:14:42.360
years uh of course those counters uh include uh setup of development machines
00:14:48.800
it includes CI it includes deploys of course uh but in any case uh that that's
00:14:55.240
the magnitude that those are the numbers and finally uh well I I was
00:15:02.240
humbled and very honored uh to be presented a couple of awards for this
00:15:07.399
work the the one on the left is an outstanding performance performance
00:15:12.839
fukoka uh Ruby award the one on the right is a rail house conference award
00:15:19.000
for zyber yeah
00:15:32.920
signatures all methods in zyber uh have documented signatures so for instance
00:15:38.680
this one is push de which is public API uh it has a notation that is uh uh I
00:15:45.160
made this my own okay it's inspired by some existing in notation but the um all
00:15:51.880
these methods public and private have signatures okay so you receive either a string or a path name and module as a
00:15:59.639
second argument this method returns nothing meaning everything every method
00:16:05.480
returns something in in in rubby but that means you cannot rely on that so you you use this method only for the
00:16:11.959
side effects right so you say that with void which is inspired by
00:16:17.160
C this method uh May raise this particular exception that's the contract
00:16:23.279
of the method okay and my reflection here is that these kind of things are not so common uh in in in Ruby in
00:16:30.880
general okay you it's very common that you open a a a source code and there's
00:16:36.279
no annotation okay uh let's talk a little bit about types types
00:16:42.199
so we have you know this this uh debate about static and dynamic typing and I
00:16:49.560
find that the debate is sometimes a little bit simplistic and dualistic for starters static typ it static typing has
00:16:57.040
evolved a lot uh with the pass of time uh so now you have it's very common to
00:17:02.319
have for instance type inference so the S quote is not so um uh verbos you could
00:17:08.679
say uh static languages uh now have macros for instance may have macros that give you
00:17:15.919
some um Dynamic nature to your code some flexibility you could say that was not
00:17:22.520
present in other types of static um uh type of um programming languages before
00:17:30.400
so there's in a spectrum okay you can write a crystal program that has zero
00:17:38.160
annotations and it's going to be compiled and it's going the compiler is is going to guarantee that it is type
00:17:44.160
safe and you did not write one single annotation in the source code it looks
00:17:49.320
like Ruby
00:17:54.480
um however there we have something in common both both the dynamic and the
00:18:00.159
static mindset as a programmer you have to know what you what the method accepts you
00:18:07.480
have to know what the method returns and you have to know the exceptions that the method raises we have that incommon it
00:18:15.760
can be expressed in an API it can be expressed in English in the documentation but it has to be there I
00:18:21.080
have to know what are you returning I have to know what you accept the
00:18:26.280
contract can be duct typing in sometime in some cases the uh this uh object
00:18:32.640
should respond to this and this and behave like that whatever you know it can be that typing but you have to you
00:18:38.679
have to know the contract otherwise how can you safely use uh that API thaty
00:18:44.919
that frame or whatever I believe this is very important in zyber you will see everything is annotated it is not
00:18:51.880
formally verified fine okay it's a dynamic language but at least it's there if
00:18:57.960
there's a mistake it's like a back you fix the mistake you move on now um some Reflections about API
00:19:06.039
design inspired by some very humble examples but that illustrate the point
00:19:12.520
okay the first thing I would like to uh explain what is my main uh driver when I
00:19:20.840
design apis my main driver is usage that's that's all I care I have to
00:19:29.600
feel that the resulting client code looks right to me okay so for instance
00:19:35.559
this is how you this is the generic API to set up a loader all right you don't see this if you are using rails because
00:19:41.559
rails does this for you there's an integration code that does this for you
00:19:46.720
but you get a loader you tell me where is the project set up done I shouldn't
00:19:51.880
need anything else and I don't that's all the rest of the rest of the code is
00:20:01.280
yours now in the case of a gem uh conventionally you know where
00:20:07.159
things are so you do not even need to have the second call there's one uh thing specialized
00:20:14.400
for gems that's all and that's you could say it's not a linear process it's not
00:20:19.880
that I sit down before I write any single line of code and I think okay this is going to be the API no the API
00:20:25.480
kind of shows up in a sense this is this is like my North Star when I write in
00:20:31.520
code I am I am at the same time kind of have a parallel thread that says okay is
00:20:37.320
is this the use that that I want uh you know for this
00:20:42.600
library now you may need to configure things if the defaults are not enough
00:20:48.480
and one case for that is inflections okay the library knows needs to know uh
00:20:54.120
needs to know how to inflect file Nam so from userb I need to know that the the the
00:21:00.080
expected constant there is user capital u that's inflecting and there's a
00:21:05.840
default inflector that all loaders have uh which does the most simple and fast
00:21:12.039
and deterministic thing that you can have there's no Global configuration every loader has full 100% control of
00:21:19.400
their uh inflector they also have a logger that's the same for loggers but you may need to configure
00:21:26.480
that one one common use case is acronyms all right so uh let's talk about the API
00:21:33.039
for doing these inflections these custom inflections how do you do that you know the the thing that you have you want to
00:21:39.120
provide an API for is to be able to express this thing I want to tell you
00:21:45.080
which is the constant path that this file uh uh should uh Define
00:21:52.120
okay so my pars is HTML pars HTML perhaps you you want to have it
00:21:57.520
capitalized you can do that all right but how how do dyber is going to ask you
00:22:04.240
for that all right so uh one possibility and this exists is that you subclass the
00:22:11.600
default inflector and you say well in this special case this is my thing otherwise I delegate with supper super
00:22:19.120
to the to the default inflector you know that's that's my Special Rule that's one way to do
00:22:24.960
it now which is the signature of this thing well a very natural one to choose is I
00:22:33.080
give you the file you give me the constant path very natural I think that if this ship it it could be no surprise
00:22:40.200
it's the natural interface to have all right uh one principle of API
00:22:46.840
design good interfaces prevent user Mistakes by Design so the user does not
00:22:52.320
even have to think about that okay uh this is a bread slicer from my
00:22:57.919
neighborhood in a supermarket all right the way it works you put bread there and there's blades and then you slice the
00:23:05.159
bread and you get the braid slice it in the supermarket okay of course there are
00:23:10.600
blades there's some danger there so what do you do about the possibility of
00:23:15.640
getting hard one way to do that is to add documentation to the thing all right
00:23:21.720
so you have to read the documentation and uh be careful about that you know that's one way to do it but there is a
00:23:28.840
better way to do it which is to remove the danger you know 100% the way to do that
00:23:35.760
is the in order to operate this machine you have to close the machine and only if it's closed those blue buttons to the
00:23:43.400
right work otherwise then do they do they do not do anything so you remove the danger all
00:23:51.000
right so I am going to remove the danger from this API the first thing that I'm
00:23:56.279
going to do is I'm not going to pass the extension the extension is meaningless you want to inflect the base name
00:24:03.080
basically okay so I do that for you you don't have to worry about the extension it's it's a small but is a point of
00:24:10.960
failure and it is redundant as information so let's remove that now I
00:24:17.640
am asking for a constant path well here we have a typo because the directory is
00:24:23.400
in plural but the name space is singular that's an error that's user error all
00:24:30.799
right um by Design zyber descends orderly
00:24:38.559
through the project tree so before hitting the HTML parser I hit my parsers
00:24:45.760
the directory The Parent Directory and I had to ask before for the inflection of
00:24:53.159
my parsers and at some point I got the information that the uh that directory
00:24:59.840
defines the my parsers constant so what happens is that I am
00:25:06.159
asking you for an information that I do not need because I have it already why should I ask you for the
00:25:13.080
full constant path when I know which is going to be the name in space so you
00:25:18.320
remove that you remove that give me giv htim password which is the inflection of
00:25:24.039
that is the base name now if you come from a legacy project maybe you need to maybe for
00:25:31.760
legacy reasons you have HTML part with lower cases in some place with upper cases in another
00:25:37.880
place maybe you need to to have some logic you know so I'm going to also give
00:25:44.279
you the absolute path in case you need it so this could be uh this could be the
00:25:51.279
contract you get the base name you get the apps path and you do the logic
00:25:57.240
now another one is that good interfaces steer users toward best
00:26:03.080
practices so I I have been uh I have had clients
00:26:09.320
that had API uppercase in some parts of the project API lower case in other
00:26:15.720
parts of the project because in classic Mode that was easy to do the result is an imer you never know
00:26:22.760
if this controller or whatever is with lower case or uppercase it's it's a mess
00:26:28.080
okay so uh good interfaces still use users
00:26:34.799
towards best practices how you make the best practice uh the path of less
00:26:40.399
resistance you could say okay you make the the best practice the first thing
00:26:45.600
that you document then maybe you need to cover all things that go second but the first thing you you you know implicitly
00:26:52.320
you are communicating to the user how to do that so why uh we do not need to have
00:27:00.880
the absolute path or anything for the base case the base case is is that I encourage you to have
00:27:08.120
API inflected in one single way in all your your code base
00:27:14.640
uniformity right so in order to you know you are saying nothing but inflector the
00:27:20.559
default inflector have a has a way to overwrite the default uh logic and this
00:27:26.880
is the API you say that API is going to be inflected as API low uppercase
00:27:33.039
extremely easy cheap to do very you know uh readable and that's
00:27:38.360
it so that was the final polish on this on this reasoning now um the the logger has API
00:27:48.279
you know to some some flexibility some options to set the logger that you want if you want if you want a logger by
00:27:55.000
default there's no logger and here I would like to illustrate that
00:28:01.080
good interfaces are knowledge symmetries so sometimes the use cases are not symmetrical and uh you do not
00:28:08.880
need a uniform API you know round that doesn't that doesn't reflect
00:28:15.600
this so I learned this in 2000 uh I was doing Java by that time
00:28:21.919
and this is the way you write a line oriented Loop in Java at least in those times okay you instant dat and input the
00:28:28.159
reader and you pass that to a buffer reader then you declare a line and you have an iterator to to Loop over them
00:28:37.360
all right I was used to this kind of apis and this is not a critique of java I have huge respect for all pling
00:28:43.919
languages so I'm just sharing a personal experience with one particular thing all right now in a table in the company I
00:28:51.600
was working at uh I found the Yama book The Yama book is the introductory book
00:28:57.039
toel and I casually browsed that book and I saw that to do the same thing in pel you do you did this same
00:29:05.880
thing super performant super compact that that is called the Dynam operator those spell
00:29:13.120
have low level interface for Io yes of course but pel acknowledges that line
00:29:19.960
oriented Loops are kind of common you know in in some kind of programs so it
00:29:26.519
it says okay this is the unit form thing with the the API po six whatever you
00:29:31.640
know but you know what this is very common so it deserves at hoc API that
00:29:37.279
that departs from the uniform from the uniformity this is the the the special
00:29:43.919
API that acknowledges the asymmetry in the use cases so very simple uh
00:29:50.600
application to zyber this is the generic one you can use this one but there is a
00:29:56.919
an extraordinary common use case which is I have this application I want to understand how is
00:30:02.600
loading maybe there's an stack Overflow question and we need to understand what is what is going on so for those use
00:30:09.880
cases this is overkill recognize that this is super super common how just lock
00:30:16.519
exclamation mark so that's all you have to do loader lock exclamation mark okay we departed from the uniformity of you
00:30:23.679
know the genericity of how to set a logger which interfaces it lock
00:30:28.960
exclamation mark is going to bring the standard output which which is what you are going to do anyway and that's it and
00:30:34.919
you know and in ra we have something similar for the same reason all
00:30:41.600
right now I would like to talk about private interfaces the question is what is the
00:30:49.519
public interface of a ruby program of a Ruby Ruby Library
00:30:55.559
framework uh I'm going to tell you what is not the public interface of a library
00:31:01.679
it is not the the the methods that have public Ruby
00:31:07.960
visibility that is not the public interface if you see a public uh method
00:31:14.440
in a class that belongs to the public interface you cannot assume that belongs to the to the public
00:31:22.120
interface why is that because in Ruby we do not have a marker for a visibility
00:31:29.679
within a library and in a in a library uh it is it is very common that
00:31:36.519
some part of the library needs to use a different part part of the library and
00:31:42.200
for technical reasons to be able to use it you need the methods to be public but that does not
00:31:49.639
mean the users can use that method that's internal okay it's technically
00:31:55.840
has to be Public public Ruby public visibility but it is internal and you
00:32:01.039
can leverage that because since you have full control on your uh internal API
00:32:07.360
maybe you can rely on things that you control maybe you control that at this if you if we hit this point uh this and
00:32:14.279
this and this is set up so I can be more performant because I can assume things that I control okay so it's not just a
00:32:21.200
matter of uh look this you can use this you cannot use it's not so easy is that
00:32:26.399
the internal apis uh are not designed for for public uh usage
00:32:33.080
typically so um Ruby does not have this concept this
00:32:40.919
many programing languages does not have this concept Ruby does not have even the concept of a gem if you think about that
00:32:47.360
the concept of gem is a construction on top of Ruby Ruby the programming language does not have libraries the
00:32:53.200
programming language has um files that you can require
00:32:58.760
that's the end of it so it doesn't even have you know a
00:33:04.880
meaning for Ruby to be constrained to library it doesn't have that concept you would need to introduce the concept
00:33:10.799
formally in the programming language to be able to do something like that now
00:33:16.720
um there are used cases that I think are valid for for for private for using private interfaces one for one is that
00:33:24.320
if you privately use it for instance in your project you know in your company uh
00:33:30.000
there's this uh back in this dependency I know that I can monkey patch this
00:33:35.880
quickly you know and I I can do anything monkey patching okay and and but it's
00:33:42.240
private it's is it's your code okay and maybe you have a guard that says if the
00:33:48.000
if you are upgrading this Library aort aort booting you cannot boot please
00:33:53.720
double check if this ticket was resolved double check if this patch is still applies otherwise delete all this thing
00:34:00.360
this is temporary okay that's I think that's a valid use case of private
00:34:05.960
interfaces um sometimes you can make that uh you know in a blog post or
00:34:11.040
something as long as you advise that you are using private interfaces so you
00:34:16.280
could say the etiquette is that if you do that and that changes in a super
00:34:21.760
minor micro patch upgrade of the library you cannot complain okay you you you
00:34:27.480
took the risk your is your responsibility that's the contract so that's that's that's all
00:34:33.320
fine but I have been I have seen private interfaces uh um you know published uh
00:34:41.159
without uh warnings all right so example code that using private
00:34:46.520
interfaces and and not with not with bath Faith uh simply people did did not
00:34:53.240
realize you know that that those were public interfaces so how to communicate that to end users one way is to use my
00:35:00.560
gem I told you it was Private that's one way to communicate to users um that that
00:35:06.920
uh they are using something private because um if you for instance have this method private interface and they find
00:35:12.880
it uh well in in your next version of the library you can um you can declare that you are
00:35:21.119
changing this private interface and then if there is code that is using that interface uh well they going to notice
00:35:29.400
they're going to notice basically the file is removed and you say ah I was I
00:35:34.480
was using uh aate interface that's why my file disappeared okay but then that
00:35:40.160
may raise questions as well so uh well that's an option but
00:35:45.280
it's not the option that I have I have a a macro call it internal okay that
00:35:51.920
defines it declares a private um visibility on the method that whose name
00:35:57.760
is received and then it generates an alas a public alas with a mangle name
00:36:02.960
okay so the intention here is that if you open the source code and you see internal death that's a
00:36:08.560
callback internal death well I think it's clearly communicating that this is
00:36:14.119
internal all right in addition to that you say you see here on file aolo that if you try to use on file aoad is going
00:36:21.400
to fail because this it has private visibility okay you you should use the
00:36:28.599
mangle name okay so uh technically you can do that okay but at least my my my
00:36:34.839
goal here is to make this a little bit more difficult to find
00:36:40.960
now a section about software errors I would like to ask the the audience if
00:36:46.720
there are people that are starting uh programming that have been programming for one year two years something like
00:36:52.760
that is there people uh starting yeah a few awesome
00:36:58.160
so while this is part of the kol for everybody this section is especially dedicated to you dedicated to you all
00:37:05.760
right so um we live in a world in which software errors
00:37:11.800
are almost take it for granted they are they are common every Everything has errors every release notes of anything
00:37:20.520
of a mobile applications of anything it's very very rare that the release
00:37:25.960
notes do not have an i item saying back fixes always back fixing always back
00:37:31.599
fixing okay that's that's a status qu okay so if you are starting
00:37:38.960
especially you may come to the conclusion that this is inevitable this is the way it works this is the way the
00:37:45.680
world Works everything has errors and we are constantly doing back fixes okay and
00:37:52.680
I want you to reflect about that because that is not necessary neily the case
00:37:58.640
that is what I want to transmit to you so I came to this realization in the
00:38:04.200
'90s in the 9s in uset something um that does not exist anymore in the tech group
00:38:11.520
I saw this sentence Tech which is a type setting system very very sophisticated with
00:38:18.200
which you you write scientific papers Tech is considered to be backf free and
00:38:24.319
it was like oh wow what it was the first time that I realized this so Tech is a
00:38:31.280
very very complex software and is considered to be back free oh that's incredible and I was
00:38:38.079
not I didn't have in mind that this was possible let's say that
00:38:43.119
way this is possible we have here an example and this is the the thing that I
00:38:48.920
want to transmit to you now zyber routinely has no issues
00:38:55.599
and no PO requests routinely it's not perfect I shipped the back fix last week okay the bastard had
00:39:03.520
been hiding for 5 years until someone hit the right you know the right combination of
00:39:10.200
things it's not perfect but if you find a back you jump on it like a lion right
00:39:19.000
you jump on it you understand the true root C root cause of the
00:39:24.720
back you fix it at T for that and ship it and now your issue
00:39:30.839
tracker is again empty and this is the perfect state for
00:39:39.160
me the perfect issue tracker is empty the perfect exception tracker your roll
00:39:44.200
bar whatever the perfect one is the one that is silent and I've seen that and I have to say uh with all humility that in
00:39:51.680
my client work that that is often the case the the exception tracker is silent there's no there's no exceptions
00:40:00.440
so this is a real example of of software that it's normal for this software to
00:40:07.440
have no nothing reported it doesn't mean it's back free you cannot do you cannot
00:40:13.040
say that but at least what you can say is that in no error is known as of
00:40:20.119
today and we have more examples of this in the rubby Community for instance anything from Jeremy Evans anything from
00:40:28.440
Vladimir demf those are projects that uh have
00:40:34.960
very few issues very very very few something even bigger than that the
00:40:40.079
Elixir progaming language The Elixir pring language we have the pleasure to have Joseph Bim in the conference which
00:40:46.119
is the creator of the programing language of alexir it's legendary I mean
00:40:51.280
they all it's it's that's complex man and they they have always under control
00:40:57.960
the issue tracker maybe they have five maybe those fives are not even back
00:41:03.040
reports maybe they are discussing some feature request or some questions you know amazing so that is the message that
00:41:11.520
I want to transmit to you do not take backs for granted do not relax and
00:41:18.119
say well this is the way it is you know so uh my message is that uh I encourage
00:41:25.920
you to think think uh independently and I encourage you to set
00:41:47.240
standards now uh some words about a
00:41:52.359
future work in zyber the main goal of zberg was to
00:42:00.960
provide out loading matching uh the way Ruby resolves
00:42:07.599
constants which was the mismatch that the classic out loader had you you
00:42:12.800
didn't get always the one that Ruby would have resolved I wanted to write something
00:42:19.200
that works that matches Ruby okay unfortunately when I wrote
00:42:25.920
that I didn't have a solution for one H case I am going to explain that ex case
00:42:33.280
to you so this is what I call in the documentation an explicit name
00:42:40.480
space so you may know that name spaces H uh represented as directories in your in
00:42:47.240
your in your file system uh some uh need only directories for
00:42:54.200
instance admin name space typically does not have admin or B and the presence of
00:43:00.319
the directories is enough to tell the autoloader hey this is a name space um I
00:43:06.760
am but uh I I have nothing to say about this name space if I if I Define a module for it is going to be empty so um
00:43:15.559
the the library automates that for you classic already did that okay so uh you
00:43:20.720
know in that case the module is created for on your behalf on the Fly and and
00:43:26.200
the things are Nam space it all right but in some cases the name space has a
00:43:33.000
file that defines the name space okay that is that is explicit the name space
00:43:39.800
is defined explicitly so this is an example okay Hotel here is an name
00:43:45.800
space this is a model all right but let's say for the sake of the example
00:43:51.760
that the logic that belongs to pricing related to pricing for just to organize
00:43:57.960
the code is extracted into a module that module is include in the class so in the
00:44:03.280
end you have the full surface anyway but from from an organizational point of
00:44:08.640
view you have that you know uh more scope in one file all right so we
00:44:14.200
extract the logic so we have hotel/ pricing RB that hotel pricing that
00:44:21.079
pricing is in the hotel liit space this is a very natural way to organize this
00:44:27.160
so this is what we we would like to do we would like to um um Define the hotel
00:44:35.520
name space uh by the way for those are starting name spaces can be both classes
00:44:41.400
and modules all right so in this case is a class and uh we would like to include
00:44:48.240
this pricing thing however we cannot just evaluate
00:44:53.359
Hotel dob why because if you if we evaluate Hotel do B Hotel colum colum pricing is
00:45:01.200
not defined so when we hit the include Line This is going to blow
00:45:06.960
up all right what about well we could perhaps load before pricing well no I'm
00:45:14.480
sorry but you need hotel in order to be able to uh evaluate the second file it's
00:45:22.000
right there in the name space so what do you do about that you cannot load any of the two
00:45:28.200
so this works in zyber okay this works and the way it works is that zyber sets
00:45:34.000
a a trace point for the class event okay this is a technical thing uh basically
00:45:39.520
when the class keyword is executed and the class is created and assign it to the constant you get called so this
00:45:46.599
callback this block is going to be called so um zyber sets this Trace Trace Point
00:45:56.280
internally and when class hotel is evaluated our call our block is
00:46:04.359
called so at that time include pricing has not been executed yet we are just in
00:46:10.520
the middle in the at the first at the top so we are on time to go and scan the
00:46:17.240
hotel directory and prepare things set up things so that when we when the block
00:46:23.079
returns pricing is already defined so pricing was we were able to execute uh
00:46:29.599
pricing at that point because hotel is already defined so that is how we solve this chicken and neck Problem by in
00:46:36.680
hijacking that thing this has worked well and she uh it has been in in zyber
00:46:43.440
since the beginning the trace point is very carefully enabled and disabled so
00:46:49.400
if you if you if there's no explicit name in space known Trace point is disabled if there's one that has not
00:46:57.440
been yet loaded we enable it and as soon as that is triggered is disabled right
00:47:04.240
so that Trace Point um uh I did benchmarks and everything has no no
00:47:10.280
overhead and we can solve this chicken neck
00:47:15.480
problem however uh there there are H cases that cannot
00:47:22.040
work with this technique and these are the ones so uh
00:47:27.880
you are Ruby allows you to Define classes and assign those classes to
00:47:33.000
constants here we have a class new is that's creating a class object and it's stored in the C constant you can Define
00:47:41.240
structs you can Define with this this new data thing you know other
00:47:47.720
classes well uh the the Callback Trace point is not called in this situation so
00:47:54.599
these kind of idioms work in in in in all normal Ruby files so that that works
00:48:02.240
okay the only place in which this idioms do not work is when they when this thing
00:48:09.359
plays the role of an explicit name space is in that particular age case unfortunately I couldn't cover this
00:48:16.520
one but in Ruby 32 and this is again a
00:48:21.599
work from John bosier we have module const added all right uh I am not going
00:48:28.200
to explain the technicalities of this uh but modulus I have not uh written the
00:48:34.960
patch I believe this solves it it this this is this is going to be
00:48:42.800
uh change in the way the library works because iberg nowaday supports Ruby
00:48:48.240
2.5 okay so I would I would require uh Ruby
00:48:55.000
3.2 in order to be able to solve uh to use this technique and I believe that
00:49:02.920
with this technique the library would be complete mission
00:49:08.000
complete 100% match so
00:49:17.359
yeah so that's going to be zyber 3 it's kind
00:49:22.839
of a small change but it deserve I believe a maor a major version and
00:49:28.640
that's all I had uh for today thank you