Man With Code 👨‍💻

In which I occasionally teach you things.

Tag: programming

Learn TypeScript #5, Basic Classes

Series: Learn TypeScript

Transcript:

Hello, everybody! Today I'm going to show you how to use classes in TypeScript. There's a lot to cover about classes, so for this video we're going to stick to the basics, and then in future videos we'll dig into the really advanced stuff.

At their core, classes are a way of describing what data you want certain objects to hold, along with methods that act on that data in various ways. There are a lot of other features built on top of this, but that is the core.

If you come from a language like C# or Java, classes in TypeScript are very similar to what you worked with there. Though there are some important differences in the low-level details, which we'll be covering in later videos.

Unlike Java or C#, however, there's nothing in TypeScript that is forcing you to use classes. So if you prefer to write your code in some other way, you are perfectly free to do so. Classes are just another tool you have in your toolbelt as a TypeScript developer.

If you've been following the development of JavaScript over the years, you'll know that the latest JavaScript standards have added support for classes. TypeScript classes build directly on these standards, but with the added benefit that you can use TypeScript to target older versions of JavaScript, and the classes you write will work perfectly well when compiled down to code that's compatible with older browsers that don't support classes in JavaScript directly.

So let's start off with a simple example class.

Let's say we're making game and we're planning on having multiple players and a decent amount of logic common to the players to handle things like movement, displaying the players, and so on. This sounds like a good candidate for a class, so let's create a class called Player.

Creating a class is very simple, we'll write the class keyword followed by our class name, and then the contents of the class are contained within curly brackets. If you saw the previous video on interfaces, you'll notice that class definitions and interface definitions share a lot of parallels, which you'll see more of going forward.

Let's pause for a moment and note that this is actually a complete class. It's empty, so it's not very useful, but before we start putting things in it, I want to show you how to create an instance of this class.

We'll create a new variable called "p", and set it equal to "new Player()".

The "new" keyword is how you indicate that you'd like a new instance of an object that's defined by a certain class. Player is obviously the name of your class, and your parentheses indicate that this is a function call.

Now, we haven't actually defined any function here, so what function is it calling? Well, all classes have what are called "constructor" functions, and if you don't create one explicitly, TypeScript will create one for you. We'll go into more detail on this in a bit.

Let's log the variable and see what it looks like.

You'll see that Node.js is actually very helpful here, showing us the class name, and then the empty curly brackets will contain the data in our object once we actually start adding some fields to our class.

So, how do we add things to our Player class?

The first and easiest way is to simply write the name of the variable, and then assign to it whatever value you want.

Here we'll say each player needs and x and a y position, so we'll set both of those equal to zero.

If we run our program again, you'll see that I have a player with an x and y of 0. Excellent!

These fields are just like the fields of any other object. For example, I can set "p.x" equal to 1, and that will do what you expect.

A note to those from other programming languages: Fields in TypeScript are all publicly accessible by default.

Just to prove to you that we have an isolated instance of our object, let's create a second variable called p2, and log that one out as well.

And you'll see it's only our original object that has changed, just as we would expect.

Going back to our class definition, note that if you wanted to be explicit about the type that you wanted a field to be, you can indicate that in the usual way by simply writing a colon and then the type that you'd like.

What we've done so far works well for fields that will always start off at some default value, but what about a case where there isn't necessarily a correct default value?

For example, let's say we wanted to give each Player a name. We'll add the name field and say that it should be a string.

But, what's a good default for that? Well, an empty string might not make much sense there. Neither would a random name. Plus then we'd have to remember to change it properly after instantiating it.

Probably what makes most sense would be for us to force the name to be specified at the creation of the object. We mentioned previously that there was a constructor function being created for us, let's define it ourselves now so that we can use it to require a name.

You can do that by going to the class definition, typing "constructor", parentheses and then curly brackets for the constructor function body.

We'll add "name" as a parameter to this function, and we'll assign "this.name" equal to the "name" parameter.

You'll see that now TypeScript is giving us errors about the places where we're creating instances of this class because we're not providing a name.

Let's name the first one "Tyler" and the second one "Fred". And now TypeScript is happy again.

A couple points of clarification on constructor functions. First, the special "this" keyword refers to the particular instance of the class that you're currently working with. Here in the constructor, that's the newly created object that we're building up.

Second, the way these default values for x and y are set by TypeScript is by moving the assignment to the very top of your constructor function.

So assigning a value to them on the same line as their definition is directly equivalent to writing "this.x = 0" at the top of the constructor function.

In general, since assigning the default value where the field is declared is more compact than the alternative, I tend to favor doing that in my own code. If you prefer to leave the declaration as only the types, and initialize all the defaults in the constructor that's a perfectly valid stylistic choice.

Note that if you're initializing something in the constructor, the field declaration must have a type on it, because otherwise TypeScript will not be able to infer what type it is that you want.

Okay, so we've got some data that we're holding in our objects, let's create a function to act on that data.

Let's say we don't think the output of console.log is quite to our liking, so we'd like some other way of displaying our Players.

Well, we can create a new method by specifying the name, the arguments in parentheses, and then we can specify the return type with a colon after the parentheses.

And we'll type out a call to console.log() that formats things a little more nicely.

And we'll run that, and hey! Things are looking pretty good.

One thing you'll notice down below is that the list of functions that are part of an object aren't included in the default console.log() output in Node.js. Generally this is fine, since the data will be more important to see, but this is something you should be aware of.

Let's tie things into the previous video by showing how we can make interfaces and classes work together.

Since we're working on a game here, I imagine we'll have a number of different types of objects that we'll want to treat generically in some kind of way. Perhaps we'll use some common fields to do collision detection or to draw them or whatever else.

To define what we need, we can create an interface listing what we'll need from each game object.

Let's say this is a 3D game, so we'll need an x y and z position.

In order to indicate that we want our player to be compatible with this interface, we can use the "implements" keyword followed by the name of the interface. Note that if you had multiple interfaces, you can separate them by commas.

Now we're getting an error about our player not implementing the interface correctly because it doesn't have the "z" field, so let's add that.

And now everything is good.

Down lower in the code, we can create an array of GameObjects, and put our two player objects in that array. Since our Player class properly implements the GameObject interface, TypeScript is perfectly happy with this.

Note that the "implements" keyword on our class definition isn't actually required as you might be used to from other languages. If we remove it, everything is still fine. The difference here is that if we were to remove our "z" field, we now get an error down in our array rather than on the class itself.

So why would you want to use the implements keyword if you can get away without it?

The biggest reason is that it will tell you while you're focused on just the class definition itself whether or not the class properly implements the interface.

It also serves as great documentation for your future self and other programmers that the specific class is intentionally conforming to some interface.

A third reason, is that some frameworks like Angular will check objects for specific methods. If they exist, Angular will call them, if they don't, Angular won't. Including the "implements" keyword and the relevant interface for that specific Angular feature will cause TypeScript to validate that you are actually including that method properly. If not, you'll get an error, which is helpful.

Okay, we'll pause here and in future videos we'll be covering things like inheritance, private, public, and protected fields, static properties, accessors, the nitty gritty details on the implementation details behind classes, and much more.

If you've enjoyed this video and want to go deeper, I'm working on a course on TypeScript. You can find it at https://typescriptbyexample.com I'm still working on it but if you scroll down to the bottom of the page leave your email address there I'll shoot you an email when that course is released.

That's it for this video! Thank you so much for watching, I will see you in the next one.

Keep reading...

Learn TypeScript #4, Interfaces

Series: Learn TypeScript

Transcript:

Hello, everybody! In today's video I wanted to show you interfaces, what they are, how to use them, etc. So let's get started!

What exactly are interfaces? Well, interfaces are a way of ensuring that the objects you're passing around throughout your program conform to your expectations. You can describe the shape of a paricular object, and the types of all its fields, and TypeScript will enforce that your expectations for that object match reality.

This becomes immensely valuable once your program starts to grow past even a few dozen lines long.

Interfaces are one of the basic building blocks of TypeScript code, and you'll see them used everywhere. Here I've opened a typings file that's internal to TypeScript itself, and if we search for interfaces we get 86 results just in this file alone! So they're definitely something you want to be familiar with.

Interfaces pair really well with classes in TypeScript, and we'll be going into detail on classes in a future video.

Let's start with some simple examples of an interface. Say we're writing a web app; we'll likely have lots of different code that will need to work with user data, so user data seems like a good candidate for an interface.

We'll create an interface using the interface keyword, followed by the name we want for it. I'll call this User.

Then we'll define the fields a user should have. Let's say we want the name as a string, the time of their first visit as a Date, and their role is going to be either a "admin", a "manager", or a "employee".

That's a complete interface!

Let's create a variable that uses this new interface. Like any other variable, we'll give it name write a colon and then the type, which in this case will be the name of our interface.

We'll then put in a name, create a new Date object which will hold the current time, and we'll say the role is "admin".

So what do interfaces look like when they're compiled? Well, TypeScript interfaces are "zero cost", which means when you compile your code they completely go away.

If we open up our compiled code, you'll see that there's no trace of our interface to be found.

This means that all the enforcement of the interfaces happens at compile time, and when your program is running, it's not going to be slowed down by interfaces in any way.

On the other hand, if you're receiving data from some external source that you've defined an interface for, TypeScript won't be able to tell you if that external source has given you valid data.

So make sure that you write your own validation code in that case to prevent any runtime errors.

If you've been following along in the series so far, you'll have seen me use the "type" keyword to create some new types that were useful for our programs.

The type keyword can describe objects in a similar way that interfaces can, but you generally won't find it used that way.

Interfaces are the standard way of saying "here's how I expect this object to look", whereas the uses of the "type" keyword are more about combining various types in various ways.

You'll see this more in the video on classes, where we'll have classes declare that they "implement" certain interfaces, and TypeScript will ensure that they actually do.

In general, if you need to create a type for some specific object, use an interface. Otherwise use the type keyword.

One interesting thing you can do is create interfaces that are based off of other interfaces.

Let's say we actually want to store some additional data on admin users. What we can do is say "interface AdminUser extends User".

Currently I haven't yet listed any fields. But if I were to change my use of type User to type AdminUser, TypeScript will continue to be happy because all the types from User have carried down to AdminUser.

For AdminUsers, let's add an array of things that they have access to.

You'll see that I now have this red underline here because the access property is missing. If we give this user access to a few things, TypeScript will be happy again.

An interesting thing interfaces can do is override fields that are defined in interfaces that they've extended.

A good example of this would be the "role" field. On AdminUsers, it's always going to be "admin", so let's specify that.

Now if I try to change myself to an employee from an admin, you'll see that TypeScript is now throwing an error.

Overriding fields like this is pretty useful, and you may see it in TypeScript code you encounter in the wild every now and again.

Another thing interfaces can specify is functions that should be a part of them. Let's say for our AdminUsers we want some way of logging their name to the console.

You'll simply write the function name, parentheses, the argument list and then the expected return value of the function.

Since it's just an interface, we don't provide any implementation for this function, that's left up to the actual instances of the object.

We'll add a function down here to satisfy the interface, and TypeScript is happy with us again.

Note that if we do something like alter the expected return type, TypeScript will helpfully indicate the error so that we know to update the usages of that interface.

Another very helpful thing you can do with interfaces is define optional properties. So let's define an optional property called "jobTitle". All that it takes to do that is to add a question mark at the end of the name. And you'll see that since it's optional, TypeScript isn't giving us an error about the jobTitle field being missing from our user object.

Of course, it will give us an error if we define the field with the wrong type.

If you have strictNullChecks turned on, an optional field can only be the type you specify or undefined. It can't be null. If you need null as a valid value, you'll need to explicitly spell that out in the type definition.

If you want to prevent people from modifying an object that implements a certain interface, you can describe certain properties as "read only" by prefixing them with the "readonly" keyword.

Let's create a variant of our User interface that is all readonly called ReadonlyUser. Perhaps we want to make sure that our user interface code is only displaying users, rather than modifying them in any way.

So now if we create a new ReadonlyUser, TypeScript will give us errors if we try to modify any of the fields.

Note that this is a fairly weak guarantee, however. If we create a variable of type User and assign our ReadonlyUser to it, TypeScript will be perfectly happy doing so, because all the necessary fields are present. But now we can modify the ReadonlyUser by way of this plain User variable.

So think of readonly as a light helper or as a bit of documentation to other programmers, rather than a strict guarantee that the field marked as read only will never change.

Moving on: a common mistake that you might make while using an interface is making a typo on one of the field names. TypeScript has a feature called "excess property checks" which aims to help prevent this kind of mistake.

Looking at our AdminUser here, let's typo the "name" field.

TypeScript is now giving us an error that this unknown field does not exist on type AdminUser, which helpfully let's us catch our typo.

However, the excess property checks only happen on object literals. So, that's situations like this where we're assigning directly to a variable, or if you were to pass an object literal to a function that's expecting an interface, TypeScript would do these checks as well.

However, if you're pulling in a variable in some other way, the excess property checks aren't going to happen.

To show you what I mean, let's change our variable declaration a little bit, and add a typo on the jobTitle field.

We'll then create a new variable of type AdminUser and assign our previously created variable to it.

Since excess property checks won't be used in this situation, TypeScript is only guaranteeing that the minimum required fields are present, which they are. The field with the typo is just ignored as extra data which isn't important to the interface.

This problem very well illustrates a general principle of how TypeScript interfaces work: TypeScript will guarantee that the object has at least the fields you describe. They might have more fields, they might have extra functions, they might have none of their optional properties, they might have whatever else. But you can be sure that they have at least what you specified.

That's especially useful to know if you're going to do something like loop over all the fields in an object. If you do that, TypeScript is only guaranteeing that you'll see the minimum required fields, but you might see more things depending on where your data came from, so you'll need to make sure your code will handle that properly.

Generally you won't run into these kinds of issues on a day-to-day basis, but it's really helpful to be aware of them for when you eventually do.

Moving on, let's say you have an object that you're using to store other objects. For example, we might want to have a mapping between a user's ID and the user data itself. You can use what are called "index properties" to describe this sort of situation.

Let's create a MapOfUsers, and we'll associate a string ID to the user data.

You'll see here in square brackets we define the type we'll be accessing with, and then after a colon outside the square brackets, we list the type we'll return with that access.

Let's use this new MapOfUsers type. We can put in our existing user, and that'll work just fine.

We could also define a new user in-line, and TypeScript will enforce that it has the proper values.

TypeScript will also enforce that you use the proper index type. Here we used strings, but we could also switch to numbers instead.

You'll see that after making that change, TypeScript indicated an error until we switched all of our values from strings to numbers.

The final feature of interfaces I wanted to show you is the ability to modify previously declared interfaces. I don't see this used very often, but it's good to know that it's something that exists.

In order to do this, you simply write out the interface keyword and the name of the interface you're going to modify. Let's let's pretend that this interface user is defined in some file A and this other one is defined in some file B. Perhaps in file B we're asking the user for their age and we want to indicate that as part of the user document.

You'll see now down here on the user we've created, we're now getting an error about age not existing. So as simple as that we added a new field to the interface. Perhaps we should mark it as optional.

You'll want to be really careful when you do this, because adding new required properties could easily break your existing code. Your code will also become harder to follow because now your interface definition is split across multiple places, so it's hard to get the big picture view of what the whole thing looks like.

The main use case for this feature is if you are modifying a library that you're using, or if you're monkey patching one of the built in JavaScript objects. Otherwise I reccomend against you using this feature.

Alright! That's it for interfaces! Stay tuned for the upcoming video on classes, which interact with interfaces quite a bit.

If you've enjoyed this video and want to go deeper, I'm working on course about TypeScript. You can find it at https://typescriptbyexample.com Scroll down to the bottom and put in your email address, and I'll let you know when the course is released.

Thank you so much for watching! I'll see you in the next video.

Keep reading...

Learn TypeScript #2, The Basics of How Types Work Pt. 2

Series: Learn TypeScript

Transcript:

Alright! Hello everybody! This video is a continuation of the previous video on basic types in TypeScript. Today we're going to go over null, undefined, using types with functions, and a few other things. If you missed the previous video, you might want to go back and watch it before you start this one.

There was one thing I wanted to clarify from the last video. I mentioned that I strongly recommended against using the "any" type unless you absolutely had to, and I wanted to explain why. The basic reason, is that when you use the "any" type, you're opting out of nearly all the checks that TypeScript is going to do for you, so if you're going to use "any" everywhere, you might as well not use TypeScript.

I know when I first started with TypeScript, I often found myself reaching for the "any" type, but 99 times out of 100 it wasn't because I needed it, but because I was being too lazy to stop and think about what the type of something should be.

If you take those few seconds to stop and think, you'll end up with a program that's better designed, you'll have code that's easier to come back to and change later, and you'll have TypeScript helping you catch errors later on down the road.

Enough about "any", let's talk about null and undefined. This is definitely one of the more confusing parts of JavaScript (and therefore TypeScript), so let's talk a little bit about what null and undefined are.

You may be familiar with null from other programming languages, and the easiest way I find to think about null is that it represents the explicit lack of any value. To use our player object example, if there's no player 2, it's possible that we'd want our player2 variable to be null.

Undefined is very similar, as it also represents the lack of any value. The key difference here, is that any variable you never assign any value to is going to hold undefined by default (though you could also explicitly set a variable to undefined, like you can set one to null).

Generally, I see null as representing a value that is intentionally missing for whatever reason. Whereas when undefined crops up in a program, it's often a mistake or accident rather than intentional, since it implys that somebody created a variable, but then never used it. Due to this, I recommend that if you need to indicate a lack of some value, use null rather than undefined, since it will be clearer to people interacting with your code that this was probably something intentional.

All that aside, how do we use null and undefined in our TypeScript programs?

You'll remember from our last video that we could use "null" as a type just like string or boolean or anything else, and the same is true for undefined.

Notice that if we create a variable and don't assign to it before we try to use it, TypeScript helpfully gives us an error.

Note also that even though variables default to undefined, we can't actually assign the value undefined or null without specifying it as part of the type of our variable.

You'll see we get the error "type undefined is not assignable to type string".

We have to explicitly list it as a possible type in order for TypeScript to accept it.

You'll see also that if we try to use this variable without checking wether the type is actually not null or undefined, TypeScript will give us an error as well, preventing us from making a common mistake where we assume a variable has been assigned some value, when really it could just as easily be null or undefined.

Now, it's important to note that TypeScript actually has a mode where it will be less strict about the usage of null and undefined. If we open up tsconfig.json and scroll down a little bit, you'll see that I have strict mode enabled. This enables all of the strict checks listed below it, but the one that is most relevant to us is "strictNullChecks".

If we disable strictNullChecks, or if we disable all of the stricter checks, then TypeScript will become more lenient on us and allow us to set any variable to null or undefined.

Generally I recommend against taking the more lenient route, because it leads to a lot of potential errors where you assume something will have a proper value when it actually doesn't. It's much better to explicitly document using the type system that a value might be null or undefined so that the proper checks can be made.

The main case for disabling strictNullChecks is if you're converting a large existing JavaScript project over to TypeScript and you don't want to have to deal with all the errors TypeScript starts throwing about not checking for null or undefined, since it's common for JavaScript developers to be more wonton about their use of null and undefined. You can still get a lot of benefits out of TypeScript without enabling strictNullChecks, but again, I recommend that you enable it.

Alright, enough of that. So far we've been defining a number of top-level variables, but your functions will need to have types as well in order to indicate the types of arguments they accept, and what values they return.

As an example, let's create a super simple function that tests whether a given number is a magical number.

We'll say that if the number we pass in is 5, then it's a magical number, otherwise it's not magical.

And you'll see TypeScript is complaining at me here, saying "parameter num implicitly has type any", which is a fancy way of saying I haven't told it what type num is, so it is forced to assume that it could be anything.

We can remedy this using syntax identical to what we used above. After the variable name, I'll simply put a colon and the type of the variable, which is number, and now TypeScript is happy with us again.

Not only is TypeScript happy with us, but if we go to use this function, our text editor can use the definition to display what the expected types of the function arguments are.

Another thing you can do is explictly specify what the return type of your function should be. We do this in nearly the same way as declaring variables, by placing a colon after the closing parenthesis and then the type.

So, for example, if we were like hey we should have been returning a boolean, we can specify that, and then TypeScript will let us know anywhere that we are returning the wrong value.

In general as I have said before, TypeScript is going to be really good at inferring what the types of things are. So, here we could have gotten rid of the return type and TypeScript would've correctly guessed that boolean was what we wanted.

However, I recommend you always type your arguments in your return values for functions, that way it's really clear to you and your team members that the function is operating in the way you intended it to operate. And it's really easy to just glance at the line of code where you create the function and get an idea of what you expect it to do.

One other type I wanted to mention that is related to functions is called the never type.

It's an peculiar type that means a function will never return. The two main examples of this are functions that you call to throw an error, or functions that create an infinite loop.

For example, something you'll see in many code bases is is a function named "fail" or "panic" or something similar. This is the function you call when things have gone horribly wrong and you need to log an error and end the program.

Since the program dies before the function fully finishes, the never type is very appropriate. It's never going to return. You can indicate that this is the case for a particular function by specifying "never" as the return type.

Likewise, if you have a function containing an infinite loop, that will also have a return value of never. The loop never stops, so the function will never return.

Keep in mind that "never" is distinct from a function that returns no value at all. For example, many times when you're working with graphics for a game or something else, you'll have some code that updates those graphics on-screen. There isn't much information this code needs to return anywhere, so it'll successfully successfully draw the graphics, and then return nothing. For that case, TypeScript has a "void" type, which you can use to indicate that the function will return at some point, but it's not going to return any value.

That's it for how to use basic types, and that wraps up this video.

If you've enjoyed what you learned here, you might like the TypeScript course that I'm working on. Head on over to https://typescriptbyexample.com, and you can put your email address in a the bottom of the page to be notified when it's ready.

Thanks so much for watching! See you in the next video.

Keep reading...

Learn TypeScript #1, The Basics of How Types Work Pt. 1

Series: Learn TypeScript

Transcript:

Alright! Hello everybody! Today I wanted to go over the very basics of how types work in TypeScript so that you can start using them in the programs you write. If you don't have TypeScript installed, please see my prior videos where I'll show you how to do that.

I've started here with an empty folder in VSCode, feel free to use any text editor of your choice as you follow along. Before we get started, we're going to open up a terminal and create a TypeScript configuration file by running "tsc --init"

We'll change one line for now, we'll uncomment "lib" and add "dom" and "es5". This will let us reference objects that exist when running JavaScript in a web browser, which I'll be using for examples later.

Now let's create our main.ts file where we'll be doing everything today.

And then we're going to go to Terminal and click Run Task and do "tsc --watch" to get TypeScript compiling our files.

We're going to start off by specifying types on simple variables. There are three ways to declare variables in TypeScript and JavaScript: var, let, and const. In terms of specifying types, they all work the same, so for this video I'll simply be using "let". In a future video I'll cover the differences between var, let, and const, but like I said, for this video, it doesn't matter.

The first thing I want to touch on before we go much further is that TypeScript is really good at figuring out what the types of things are supposed to be without you needing to explicitly declare it.

For example, you can see here in Visual Studio Code we can figure out what the type of something is by hovering our mouse over, and we see that it pops up what it knows about this variable. It says "bar: number" which means it's already figured out that this variable is a number!

However, you'll often want to explicitly tell TypeScript what the type of something is, so that's what we'll be focusing on in this video. Now, as it turns out, that same syntax VS Code showed is what you'll use to explicitly tell TypeScript what the type of something is.

We can say here "let bar: number", and TypeScript will start enforcing that this variable can only ever be a number.

You'll see if we try to change the value to something else, we'll get a red underline, an error listed below, that this string is not assignable to type number.

And, just to be clear, if we remove the ": number", we still get the same error, because TypeScript is going to assume that once you assign a variable a value of one type, that it was probably a mistake to use any other type.

Let's start with the what the most basic types are in TypeScript: booleans, numbers, and strings.

A boolean can be either true or false.

A number can be any number you like.

And a string can be any text that you like.

Building on top of the basic types, we can do arrays of things by specifying the type and then writing an opening and closing square bracket.

There is an alternate syntax for writing arrays, though generally I don't see it used as often. Instead of using the square brackets, you write Array, an angle bracket, the type contained in the array, and then a closing angle bracket. This is completely the same as the other syntax used above, and like I said, this is used much less commonly so I say default to the first way unless you have a good reason to do otherwise.

There's also a variation on arrays called a tuple. If you're not familiar with the term, you can think of it simply as an array with a fixed number of elements.

Say there are two pieces of data you always want to store next to each other, but don't want to use a full object for whatever reason, you could do that with a tuple. For example, we could store student test scores as a tuple containing their name and the score.

Here, Tom has a score of 97.5.

And and you can see this is expecting just a string and a number. If we tried to add something extra to this, it's going to complain to us that we've created something that's not the size that we said it would be or if we try to remove a required element TypeScript will also complain. And similarly if we use the wrong type it'll complain as well.

To be clear, you can have an array of tuples by combining the same syntaxes we've just learned. So we'll have our tuple type followed by the opening and closing square brackets.

And then we would fill it out like so, and TypeScript will enforce that all the types we use here are correct.

Declaring our own objects is done in a very similar way to arrays. Let's say we're making a game, and we have a player with an x position, a y position, and some health. How would we do this in TypeScript?

We'll start by declaring our player variable, then doing a colon and some curly brackets, and inside the curly brackets we can put the names and types of the fields we want to create. You'll see that this looks very much like the actual object value that we'll assign to the player object.

If we accidentally put in the wrong type, or if we add a field that doesn't exist as part of the definition, TypeScript will complain at us.

It'll often be the case that you'll want to re-use object definitions like this in multiple places, say if you had multiple players or various functions that manipulated player objects.

There are two ways of doing this, the first and most direct way is to use the "type" keyword to define a new name that is equal to the type we defined for players earlier.

Then we can use that name in place of the full object definition for the player.

Another option with very similar effects is to create an interface. You can do this by using the "interface" keyword followed by the name you want, and then describe the types of the fields for the object like we did earlier. We can use it as the type for our player in exactly the same way that we used the definition created by the "type" keyword.

When is it appropriate to use "type" instead of "interface"? The answer is a bit too long for this video, so stay tuned for a future one where I'll cover that. For now, just use whichever one you feel most comfortable with.

Now, going back to our example, you can see that I can now create a second player using the same type.

And if I update the definition of the type, TypeScript will helpfully give us an error on both of them, indicating that they need to be updated to match the changes.

This feedback loop is super common in development. You'll often notice some object needs a new field, or needs that field altered in some way. You can make that change in the central type definition, and then go through and fix each of the places where TypeScript indicates that there's a problem. No need to worry about whether you updated every spot or not, TypeScript will let you know.

Now is a good time to mention that in the same that way we created and used our own types above, we can use existing types that are part of JavaScript or JavaScript's environment. For example, because we included "dom" in our "lib" in tsconfig.json, we can create a variable and declare that it's type is HTMLElement. We could then fill this variable with something from the DOM API, like document.getElementById.

Now, you'll see here that TypeScript is complaining about our HTMLElement variable. Why is it doing that? Well, if we hover over document.getElementById, we'll see that the type is actually "HTMLElement | null", the pipe character there means "or". That's because if we specify an ID that doesn't exist on the page, this function will return null.

Using the pipe character to join multiple types together creates what's called a "union type", which is simply a fancy way of saying "this variable could be a few different things". There's a lot more to union types, and other related features in TypeScript that we'll cover in a future video, for now, just be aware that if you have a variable that could be a couple different types, you can list those types by separating them with the pipe character.

Okay, so that covers the basics of builtin types and defining our own types. There's a couple of catch-all types that I want to show you.

The first one is an "object", and that represents anything that isn't a basic type. So it'll be anything that isn't a boolean or a number or a string. For example, it could be HTMLElement or our Player type, or anything else. This is a type that I don't see used all that often, because generally you either know what the object type is, or you use the even more general "any" keyword.

"any" is exactly what it sounds like. If you say the type of your variable is "any", you're saything that it can hold any value possible. Generally if you're using TypeScript, I strongly recommend against reaching for "any" unless you absolutely have to use it. Though if you're interacting with non-TypeScript code, it can be appropriate to use "any" in order to deal with JavaScript libraries that truly can produce any value.

Next up is talking about how to handle null, undefined, and how to use types with function definitions, but this video is already running a little long, so stay tuned for part 2 of this video.

If you're enjoying what you're learning here, you might like the TypeScript course that I'm working on. Head on over to https://typescriptbyexample.com, and you can put your email address in the form at the bottom of the page to be notified when it's ready.

Thank you so much for watching. I'll see you in the next video.

Keep reading...

What is TypeScript?

Series: Learn TypeScript

Transcript:

So what is TypeScript?

At a super high level TypeScript is JavaScript with static type checking. What that really means is that you no longer have to write JavaScript code purely based on faith and good guesses that the variables and objects you're using are what you think they are.

TypeScript is going to come along side you and enforce that "hey this is a string this is a number this is you know some object with a certain felds" TypeScript is going to add those guarantees so that you can code with more confidence.

In practice you'll find that you'll have fewer dumb errors; If you're working on a team, it becomes vastly easier to communicate what certain code does because they can see right there what the types are and when they go to use them TypeScript is going to tell them if they're using them erroneously.

It is easier to communicate with your future self so that when you come back to your code it's easier to tell how things work. You can just look and see what the types of various objects are without having to go back and actually run the program to see if the guesses you're making about the program are actually true.

In short, the code has become much more self-documenting

If you go to the TypeScript website you'll see Microsoft describes TypeScript as "JavaScript that scales". What does that really mean?

What it has meant in my experience is that you can bring a team of people together or you can work on something yourself and you can build programs and applications that very large and complex and you'll going to have much more confidence in what your building and in and how you're managing the complexity then you would be if it was just plain JavaScript.

I can recall numerous times on plain JavaScript projects before we started using TypeScript that I would go to refactor something or move some code around or change some logic or whatever and I could never be entirely sure that I hadn't broken something. Even if my tests pass even if in my manual testing everything was working right, I was never able to be fully confident in the changes I had made. It seems like there would always be something flew under the radar that got missed.With TypeScript that happens far far less often, in fact I'd say almost never.

TypeScript is a strict superset of JavaScript. What that means is that anything you know about JavaScript you can transfer into your knowledge of TypeScript. There are definitely new things to learn, but it's not a whole new world that you'll be completely lost and confused in. If you already know JavaScript, you'll be good to go.

In a lot of cases you can take code that you've already written in JavaScript change the file extension from .js to .ts and everything will work, or most of it will work with maybe a few extra type annotations that you need to add in. So it's very straightforward to get started and to jump in.

Another great thing about TypeScript is that it compiles directly to JavaScript. In practice that means that you don't have to install any extra runtime or ship any additional library to your users in order to start using TypeScript in your application. In development, you'll just run the TypeScript compiler and then away you go.

Since it's just plain JavaScript you can use the same debugging tools that you're already used to. You can also graudually introduce TypeScript into an existing JavaScript project, slowly converting files to TypeScript bit by bit as you go along.

If you've used other languages that compile to JavaScript, you might be used to the compiled code looking unintelligible, very much like a machine wrote it. In most caess, TypeScript is merely erasing your type annotations, so your original code remains. In cases where it does have to manipulate things, I've found it makes very readable choices about the code it produces.

Anothing great thing about TypeScript too is that it supports many of the new features that have been added to JavaScript in ES6 and other newer JavaScript versions. Not only that, but you can have TypeScript compile to older JavaScript versions so that you can use the latest features in TypeScript, but still support older browsers.

One thing I wanted to mention as well is that the types are in a lot of cases optional, or what you might call a gradual, or can be inferred by TypeScript. That means there's a lot of cases where you don't really need to tell it what the type of something is, it'll see "hey I'm setting this variable to a string so that must be a string", and you don't have to do the redundant typings that you might have gotten used to if you came from a C# for a Java background, and that's really nice.

Also, depending on the configuration flags you set and how much you use the catch-all "any" type, you can use the type checking as much or as little as you want. If you want it to be super strict and have types everywhere, you can, or if you want to write JavaScript in the more dynamic untyped way that you're used to, you totally can.

I think TypeScript helps enforce some good habits in a few different ways. First, once you get used to the typings, it becomes very natural when writing new code to sketch out the interfaces and relationships between data before you start writing code, because you can use those right away when you start actually implementing your program, rather than just leaving them as inert comments or notes or thoughts in your head.

Second, depending on how you configure TypeScript you can make it so it's much more strict about checking for null and undefined, which is a really good habit to get into.I've been guilty myself of getting lazy and thinking "well this could fail as null or undefined, but I'm just going to ignore it because it makes my code a lot simpler." But if TypeScript is yelling at me I'm much more likely to do the proper thing and that's really good.

Third, if you're defining a type and it becomes hard to think about or it hard to describe a lot of times that's been an indication to me that "hey I'm making this more complicated than it needs to be" or I'm I'm trying to do this in a way that might be clever now but it isn't going to stand up to the test of time. I'm going to come back to this later be super confused or I'm going to have to hand this off to a co-worker and they're going to be super confused.

Better IDE support is one thing that's great is if you're using something like Visual Studio Code or JetBrains WebStorm or any other IDE or Smart Text Editor with TypeScript. You get way better auto completion so you can access things or call functions and it's going to tell you "hey this is how you call this thing" or "hey that's an error you missed a parameter here" and that kind of thing.

If you've used just plain JavaScript in the past, you'll know that IDEs can be pretty good about guessing what things might be, but there's a lot of times where you'll start typing a piece of code and it does the auto-completion and gives you every possible field name that I've defined in my project as an option. Which is massively unhelpful. With TypeScript you avoid that issue entirely, since it knows what the types of things are, you get vastly better auto completion support. Which makes you a much happier and more productive programmer.

So that's a general overview of what TypeScript is. I hope that was helpful to you! I've got other videos out there on TypeScript, so if you want to learn more, please check them out!

If you visit https://typescriptbyexample.com you'll see some info on a course that I'm building for TypeScript. You can put your email address in at the bottom of the page and you'll be notified when that's ready. I'd love to hear from you, and I'd love to have you be a part of the course. Thank you so much for watching! Goodbye!

Keep reading...

How to Install TypeScript on Linux

Series: Learn TypeScript

Transcript:

Alright! Hello everybody! So, I wanted to show you how to install TypeScript on Linux. Before we get started, a word of caution. Every Linux distribution is a little bit different, in theory everything I show you here should work across most distributions, but it's possible that yours might do something a little different. For reference, I'm using Ubuntu 18.04.1 LTS release for this video.

One thing I want to point out before I get started is that most Linux distributions have some sort of package management system that you may be able to use to install TypeScript. For example, Ubuntu offers the node-typescript package, which you can install via apt.

The problem is that these package managers often contain old versions of TypeScript, and TypeScript releases quite frequently, so today I'm going to be showing you how to install TypeScript directly from the source so you can be running the latest and greatest version.

So, to get started we're going to open up whatever your favorite browser is, or whatever browser you have installed. Here I'm going to be using Firefox.

We are going to head over to https://nodejs.org Now, you'll see a page like this. It'll give you a couple of different download options and you can opt for either the LTS or the current release.

Either one of those works. I'm going to say go for the LTS version. That's because that stands for long-term support, so this is the version that's going to keep getting security updates and things like that.

That's probably the one you'll want to go with. If you want to be on the bleeding edge, and have the latest and greatest feel free to go with the other one, it will work just as well.

For this video I'm going to go with 10.15.1. Very likely if you're watching this at any point in the future these version numbers are going to be different. Node.js does a lot of releases so, it's totally okay if you're on a later version than I am. Everything should work just as well.

Download it.

Alright, it has finished downloading, so let's open a Terminal and extract the files and get started.

Here I've opened the default Terminal that comes with Ubuntu. We're going to do:

cd Downloads

to get to our downloads folder.

We're then going to type:

tar xvf node-v10.15.1-linux-x64.tar.xz

Hit enter. It'll print out the files it unzipped and then we should be able to see the new folder.

Next we need to add Node.js to our PATH. We can do this by typing:

export PATH=~/Downloads/node-v10.15.1-linux-x64/bin:$PATH

Now that Node.js is on our PATH, we can test if Node.js is installed properly by typing:

node

and hitting enter.

And this little angle bracket should appear. And we can start entering JavaScript code here.

So, two plus two is four. Let's see, we could do a setTimeout. So in 5 seconds that should display something. There it is.

If you want to get out of here just hit CTRL+C. Twice. And then you're back on the normal Terminal prompt.

In order to use Node.js and TypeScript in future Terminal sessions, we'll need to put that PATH line at the end of your .bashrc or .bash_profile file, or whatever profile file your shell of choice uses if you're not on bash. To do that I'm going to open up Ubuntu's default text editor.

We'll hit open, and navigate to our home directory. Note that you'll need to ensure that hidden files are showing. I can do that here by pressing CTRL+H. I'll open .bashrc, copy that line from before, paste it to the bottom, and then save the file. And then, hey presto, any subsequent Terminals we open will have Node.js available to us.

So, all that out of the way, let's install TypeScript! In order to install TypeScript we're going to use something called npm. If you're unfamiliar with npm that stands for the node package manager and that's how lots of different Node.js based libraries and programs are distributed, TypeScript among them.

How do we use npm to install it? Well, here in this Terminal we're going to type:

npm install --global typescript

And hit enter.

Note that if you've installed Node.js and npm from your package manager, you may need to prefix the previous command with sudo to run it with root priviledges

And you'll see here it says added one package from one contributor in 1 second.

Now it's very likely that you'll see a different version number here. TypeScript also like Node.js releases fairly frequently. TypeScript is really good about backwards compatibility, so you shouldn't have to worry about anything you see in this video or any later video being incompatible.

If you wanted to be on the exact version that I am going to show you, though, what you can do is go back to the Terminal and run:

npm uninstall --global typescript

to get rid of what we just installed.

And we'll then run a command similar to what we did before:

npm install --global [email protected]

When you add that @ sign and then the version number, it's going to guarantee that that's the version you're going to install rather than whatever the latest is (which is the default).

There we go. We've got that working.

So now what I'm going to do is create a new folder on the desktop. We're going to call it "test" and we're just going to see if TypeScript is working.

Let's open up "test".

We're going navigate our Terminal to this new folder as well. You can do this by typing:

cd ~/Desktop/test

Once you've done that we're going to create a file named main.ts. All TypeScript files end in .ts.

You can do this by entering the comand:

touch main.ts

You'll see the file appears in the folder.

Now let's put something in this main.ts file for TypeScript to compile. So, we're going to open up the default text editor that comes with Ubuntu. If you have a particular text editor that you prefer, feel free to use it.

I'm going to go to Open and find main.ts in the folder on my Desktop.

And then we'll put in the simplest possible "Hello, World!" program and save it.

console.log("Hello, World!");

Now in order for TypeScript to compile our "Hello, World!" program it needs a configuration file.

We can create the default one by going back to our Terminal and running:

 tsc --init

When we hit enter, it's going to create that file for us. So, you can see this tsconfig.json file has been created.

Don't worry too much about that file I will be creating a video explaining exactly what it is, why we use it, how to use it, what the different options inside it mean for now all we need to know is that we need it there and now we have it.

And to get TypeScript to compile our main.ts file, just run:

tsc

and hit enter. It will find all the TypeScript files in this folder and compile them. You see we now have a main.js file.

We'll run that main.js file through Node.js:

node main.js

And see we've got "Hello, world!"

Awesome! Exactly what we wanted.

So everything's working. If you're seeing the same thing, hey you're good to go, you've got TypeScript installed.

There is one other thing I wanted to show you: You can have TypeScript watch for changes, rather than having to rerun it each time you change something. So, what we're going to do is do is go back to our Terminal and enter:

tsc --watch

See it gives us a little message "starting compilation in watch mode".

And then I'm going to go back to our file and say "Hello World! Again!" and I'm going to save it. And you see that flashed a bit. It said "file change detected", "0 errors".

We're going to open up another Terminal and do the same:

cd ~/Desktop/test"

that we did before.

You can see if we run our main.js, hey! It says "Hello World! Again!" just like we wanted.

One thing that's really nice about this is that if you make a mistake, here I'm going to forget to have the closing parenthesis and semicolon, if we save this TypeScript is going to give us an error and say "hey! I expected a closing parenthesis here!"

So we can add that back in and save it and everything's happy again.

Very cool! That's it! You've got TypeScript installed!

By the way if you're interested in going deep into learning TypeScript I've got this TypeScript by Example course that I'm working on now. You can head on over to https://typescriptbyexample.com Scroll down to the bottom, and you can put in your email address to be notified when the course is released. Also, stay tuned to this YouTube channel for future updates. Thank you so much for watching!

Keep reading...

How to Install TypeScript on macOS

Series: Learn TypeScript

Transcript:

Alright! Hello everybody!

So, I wanted to show you how to install TypeScript on macOS.

So, first things first we're going to open up whatever your favorite browser is, or whatever browser you have installed. Here I'm going to be using Safari.

We are going to head over to https://nodejs.org

Now, you'll see a page like this. It'll give you a couple of different download options and you can opt for either the LTS or the current release.

Either one of those works. I'm going to say go for the LTS version. That's because that stands for long-term support, so this is the version that's going to keep getting security updates and things like that.

That's probably the one you want to go with.

If you want to be on the bleeding edge, and have the latest and greatest feel free to go with the other one, it will work just as well. For this video I'm going to go with 10.15.1.

Very likely if you're watching this at any point in the future these version numbers are going to be different. Node.js does a lot of releases so, it's totally okay if you're on a later version than I am. Everything should work just as well.

Download it.

Alright, it has finished downloading, so I'm going to go to my Downloads folder and open it.

We're just going to click through here.

We'll hit continue.

We'll hit continue again. It'll prompt us to agree to the license, click agree.

It'll take 60 megabtyes of space, that's fine by me, hit Install.

Enter your account password at the authorization prompt and hit Install Software.

Give that a few moments. Alright, and Node.js has been installed! Hit Close.

We don't need the installer any more, so just hit "Move to Trash" here.

So, how can we verify that things are working here?

Well, let's go to the application search in the top-right corner of the screen and look for "Terminal".

Here we've got our Terminal. The way we can test if Node.js is installed properly is to type:

node

and hit enter.

And this little angle bracket should appear.

And we can start entering JavaScript code here. So, two plus two is four. Let's see, we could do a setTimeout. So in 5 seconds that should display something. There it is.

If you want to get out of here just hit CTRL+C. Twice.

And then you're back on the normal Terminal prompt.

So, let's install TypeScript.

In order to install TypeScript we're going to use something called npm. If you're unfamiliar with npm that stands for the node package manager and that's how lots of different Node.js based libraries and programs are distributed, TypeScript among them.

So, how do we use npm to install it? Well, here in this Terminal we're going to type:

sudo npm install --global typescript

And hit enter.

Enter our password. Give that a few moments to do its thing.

And you'll see here it says added one package from one contributor in 6 seconds.

Now it's very likely that you'll see a different version number here. TypeScript also like Node.js releases fairly frequently. TypeScript is really good about backwards compatibility, so you shouldn't have to worry about anything you see in this video or any later video being incompatible.

If you wanted to be on the exact version that I am going to show you, though, what you can do is go back to the Terminal and run:

sudo npm uninstall --global typescript

To get rid of what we just installed. And we'll then run a command similar to what we did before:

sudo npm install --global [email protected]

When you add that @ sign and then the version number, it's going to guarantee that that's the version you're going to install rather than whatever the latest is (which is the default).

There we go. We've got that working.

So now what I'm going to do is create a new folder on the desktop. We're going to call it "test" and we're just going to see if TypeScript is working. It's installed but is it actually working?

Let's open up "test". We're going navigate our Terminal to this new folder as well. You can do this by typing:

cd Desktop/test

Once you've done that we're going to create a file named main.ts. All TypeScript files end in .ts.

You can do this by entering the comand:

touch main.ts

You'll see the file appears in the folder.

Now let's put something in this main.ts file for TypeScript to compile.

So, we're going to open up TextEdit. If you have a particular text editor that you prefer, feel free to use it. TextEdit is all I've got on this particular machine at the moment. I'm going to go to File -> Open and find main.ts in the folder on my Desktop.

And then we'll put in the simplest possible "Hello, World!" program and save it.

Now in order for TypeScript to compile our "Hello, World!" program it needs a configuration file.

We can create the default one by going back to our Terminal and running:

tsc --init

If we hit enter, it's going to create that file for us. So, you can see this tsconfig.json file has been created.

Don't worry too much about that file I will be creating a video explaining exactly what it is, why we use it, how to use it, what the different options inside it mean for now all we need to know is that we need it there and now we have it.

And to get TypeScript to compile our main.ts file, just run:

tsc

It will find all the TypeScript files in this folder and compile them. You see we now have a main.js file.

We run that main.js file through Node.js, and see we've got "Hello, world!"

Awesome! Exactly what we wanted.

So everything's working. If you're seeing the same thing, hey you're good to go, you've got TypeScript installed.

There is one other thing I wanted to show you: You can have TypeScript watch for changes, rather than having to rerun it each time you change something.

So, what we're going to do is do is go back to our Terminal and enter:

tsc --watch

See it gives us a little message "starting compilation in watch mode".

And then I'm going to go back to our file and say "Hello World! Again!" and I'm going to save it. And you see that flashed a bit. It said "file change detected", "0 errors".

We're going to open up another Terminal and do the same "cd Desktop/test" that we did before.

You can see if we run our main.js, hey it says "Hello World! Again!" just like we wanted.

One thing that's really nice about this is that if you make a mistake, here I'm going to forget to have the closing parenthesis and semicolon, if we save this TypeScript is going to give us an error and say "hey! I expected a closing parenthesis here!"

So we can add that back in and save it and everything's happy again.

Very cool! That's it!

You've got TypeScript installed!

By the way if you're interested in going deep into learning TypeScript I've got this TypeScript by Example course that I'm working on now.
You can head on over to https://typescriptbyexample.com

Scroll down to the bottom, and you can put in your email address to be notified when the course is released.

Also, stay tuned to this YouTube channel for future updates. Thank you so much for watching!

Keep reading...

How to Install TypeScript on Windows

Series: Learn TypeScript

Transcript: Alright! Hello everybody! So, I wanted to show you how to install TypeScript. So, first things first we're going to open up whatever your favorite browser is, or whatever browser you have installed. We are going to head over to nodejs.org. Now, you'll see a page like this. It'll give you a couple of different download options and you can opt for either the LTS or the current release. Either one of those works. I'm going to say go for the LTS version. That's because that stands for long-term support, so this is the version that's going to keep getting security updates and things like that. That's probably the one you want to go with. If you want to be on the bleeding edge, and have the latest and greatest feel free to go with the other one, it will work just as well. For this video I'm going to go with 10.15.1. Very likely if you're watching this at any point in the future these version numbers are going to be different. Node.js does a lot of releases so, it's totally okay if you're on a later version than I am. Everything should work just as we;ll. Download it. Antivirus just finished scanning it, and here it is it's open. You might need to go find it in your downloads folder and double-click on it. I just had it run when I download it. We're just going to click through here. We're going to accept the license agreement. We're going to accept the default install path. We're going to leave all these things on the defaults. Install. We get our security prompt here will say yes so that it can install. Give that a few moments. Alright, and Node.js has been installed. So, how can we verify that things are working here? Well, let's go to the start menu there should be something called Node.js command prompt in there and Node.js itself in your start menu. You might have to search for it. Here it's showing up under my recently added. So if we go in here we have an Node.js command prompt. This looks very much like any other command prompt you may have seen. Just for comparison, Let's open up the other one. You can see normally for just a plain old command prompt we get the windows version information. But here we're actually getting the Node.js version information. So, we can tell that things are working already. The way you can test Node.js is type node and hit enter. And this little angle bracket should appear. And we can start entering JavaScript code here. So, two plus two is four. Let's see, we could do a setTimeout. So in 5 seconds that should display something. There it is. If you want to get out of here just hit CTRL+C. Twice. And then you're back on the normal command prompt. So, let's. install TypeScript. So, alright so to install TypeScript we're going to use something called npm. If you're unfamiliar with npm that stands for the node package manager and that's how lots of different Node.js based libraries and programs are distributed, TypeScript among them. So TypeScript is written in JavaScript and it is distributed Via npm because it runs on Node.js. So, how do we use npm to install it? Well, here in this Node.js Command Prompt we're going to type npm install --global typescript . Going to hit enter. Give that a few moments to do its thing. And you'll see here it says added one package from one contributor in one second. Now it's very likely that you'll see a different version number here. TypeScript also like Node.js releases fairly frequently. TypeScript is really good about backwards compatibility, so you shouldn't have to worry about anything you see in this video or any later video being incompatible. If you wanted to be on the exact version that I am going to show you, though, what you can do is we're going to do:
npm uninstall --global typescript
And similar to before we're going to do:
npm install [email protected]
and so if you add that @ sign and then the version number, that's going to guarantee that that's the version you're going to install rather than whatever the latest is which is the default. There we go. We've got that working. So now what I'm going to do is create a new folder on the desktop. We'going to call it "test" and we're just going to see if TypeScript is working. It's installed but is it actually working? We're going to open up "test". We're going to create a new file. We're going to call this main.ts. All TypeScript files end in .ts So, if you do what I did there and go to "New Text Document" it might not let you edit the file extension depending on what you're doing, and you could end up with something that's actually.ts.txt, which really isn't what you want. The way you can check for this is you can go to this View tab that's up here and make sure this "file name extensions" checkbox is checked. You can see if I uncheck it the file extension goes away, and you can't tell what it is. If I check it it tells me we've got main.ts which is what we want. So we're going to move our Command Prompt into this folder. How do you do that? I'm going to click here to get the full path to this folder. Then type cd which stands for "change directory" and do a quote. If you right click it's going to paste what you just copied. We're going to do an end quote. And here we are in that folder. Now in order for TypeScript to compile something it needs a configuration file. We can create the default one by running:
tsc --init
If we hit enter, it's going to create that file for us. So, you can see this tsconfig.json file has been created. Don't worry too much about that file I will be creating a video explaining exactly what it is. Why we use it, how to use it, what the different options inside it mean for now all we need to know is that we need it there and now we have it. Now before we go compiling anything with TypeScript we should probably put something in this main.ts file for TypeScript to compile. So, we're going to open up notepad. Feel free to use any other text editor of your choice. That's just all I've got on this particular machine at the moment. And we're going to go in, and I'm going to switch this over to "all files" so I can see my main.ts and we're just going to write a super simple "Hello, world!" program. There you go, there's your "hello world". Hit CTRL+S to save it. Minimize that. And then to get TypeScript to compile your files. Just run tsc. It will find all the TypeScript files in the folder and compile them. You see we now have a main.js file. We run that made that main.js file through Node.js. And see we've got "Hello, world!" Awesome! Exactly what we wanted. So everything's working. If you're seeing the same thing, hey you're good to go, you've got TypeScript installed. One other thing I wanted to show you. Was that you can have TypeScript, rather than having to rerun it each time you change something, you can have TypeScript watch for changes. So, what we're going to do is do:
tsc --watch
We're going to hit enter. See it gives us a little message "starting compilation in watch mode". I'll move this so you can see it, and then I'm going to say "Hello World! Again!" and I'm going to hit CTRL+S to save right now. And you see that flashed a bit. It said "file change detected", "0 errors". We're going to open up another Node.js Command Prompt. Do the same thing we did before so we can run this. You can see if we run our main.js, hey it says hello world again just like we wanted. One thing that's really nice about this is that if you make a mistake, here I'm going to forget to have the closing parenthesis and semicolon, if we save this TypeScript is going to give us an error and say "hey! I expected a closing parenthesis here!" So we can add that back in and save it and everything's happy again. Very cool, you've got TypeScript installed! By the way if you're interested in going deep into learning TypeScript I've got this TypeScript by Example course that I'm working on now. You can head on over to typescriptbyexample.com. Scroll down to the bottom, and you can put in your email address to be notified when the course is released. Also, stay tuned to this YouTube channel for future updates. Thank you so much for watching!
Keep reading...

Programming With Ruby Episode 17, Getting Advanced

Series: Ruby Programming

Covered In This Episode:
  • Symbols
  • eval
  • Bindings
  • Running Other Programs
  • Safe Levels
Transcript: Hello Everybody and welcome to Programming With Ruby Episode 17, Getting Advanced. I'm Tyler, and this video is brought to you by manwithcode.com. By now, you know a large amount about Ruby, so in this episode we will be going over some advanced features that Ruby has. More specifically I will be teaching you what Symbols are, and when to use them. I will be showing you how to use eval, and how to use bindings with eval. You will learn how to run other programs from Ruby. Finally I will show you what safe levels are. Lets get started! Symbols Symbols are a type of variable that are very much like strings, but more lightweight. Symbols look like this: [source language="ruby"] :variable [/source] Symbols can't be manipulated like strings can, which seems like a huge drawback, but they do have a couple benefits. Each time you use a string, to say access a hash. Ruby creates an instance of that string. Where if you use a symbol, it is only ever instanced once. Meaning that the use of symbols will take up less memory than strings will, if you are, say accessing a hash many times. Symbols are also slightly easier to type since the colon is on the home row on US keyboards. eval eval is a way of running Ruby code that is contained in a string. For example, lets say you have a string that looks like this: [source language="ruby"] "puts 'Hello World'" [/source] It is just a simple string, so it does nothing. But, if you use the method eval on that string it will execute the code inside. So this will print Hello World! on to the screen: [source language="ruby"] eval "puts 'Hello World!'" [/source] This isn't always useful, but you can use it if you want your users to be able to enter Ruby code into your program. You can also pass bindings to eval. So if we had this method [source language="ruby"] def my_method my_binding eval "puts x", my_binding end x = 5 my_method binding [/source] This outputs: [source] 5 [/source] Some of you may notice that the variable x isn't defined in the method my_method. By using the binding method, we can make variable scopes portable! Running Other Programs There comes a time when you will want to be able to run a program from Ruby, maybe you want to automate something, or simply get the output from an external program. There are a few ways of doing this. The first is with the method exec, which runs an external programs, and quits the Ruby script at the same time: [source language="ruby"] exec('ls') # dir on windows # Program never gets here [/source] There is also system, which does the same thing, but doesn't quit the Ruby script, and returns true or false if the program was successful: [source language="ruby"] system('ls') # dir on windows # we do get this far [/source] Finally we have the "back-tick" `. Which looks like a sideways single quote. On my keyboard it is above the tab key. You surround your command in the back-ticks, like you would for a sting. Unlike the other two methods of running a program, this method also returns the output of the program you run. [source language="ruby"] variable = `ls` [/source] Safe Levels If you are running a Ruby interpreter online or in another environment where users can enter in and run Ruby code. They hold the ability to wreak havoc on your system. The way to prevent this from happening is by using safe levels. Safe levels are a way of preventing the user from getting access to the file system, or changing any variables that the program has. You set safe levels by setting the $SAFE variable. By default it is set to zero. [source language="ruby"] $SAFE = 4 [/source] Ruby "taints" objects that could be dangerous. There are five different safe levels. 0 => The default, you can do anything 1 => Can't use environment variable, eval, load, require, and more. 2 => Same as above and also can't use files 3 => All objects created are tainted, can't be untainted 4 => You can do almost nothing... Can't modify the untainted, can't use exit. Basically completely safe and sand-boxed. That brings us to the end of the episode. If you liked these videos, please donate. It costs me in both money and time to make them. If you have any questions, comments, or suggestions please don't hesitate to leave a comment on this page or email me at [email protected] Thanks for watching, goodbye!
Keep reading...

Programming With Ruby Episode 16, Benchmarking

Series: Ruby Programming

Covered In This Episode:
  • What is benchmarking?
  • Benchmarking
  • Profiling
Transcript: Hello Everybody and welcome to Programming With Ruby Episode 16, Benchmarking. I'm Tyler and this video is brought to you by manwithcode.com. In this episode I will tell you what benchmarking is. You will learn how to preform benchmarking tests on some of your code. And after that you will learn how to preform the more exhaustive benchmarking process called profiling. This should be a very quick and easy episode, so lets get started! What is benchmarking? Basically benchmarking is measuring how fast your code runs. Whether that means your code as a whole or only parts of it. This can be useful so you can optimize your code to run faster, in the places it is running the slowest. Benchmarking is also commonly used to compare two different programs in the category of speed, which can be a selling point for many products. Benchmarking To get access to benchmarking make sure you put: [ruby] require 'benchmark' [/ruby] in your code. The most simple form of benchmarking is Benchmark.measure: [ruby] a = Benchmark.measure do 1_000_000.times do |i| x = i end end puts a #=> 0.400000   0.140000   0.540000 (  0.537934) [/ruby] The last number is the actual time it took to run the test. There is also Benchmark.bm, which is similar, but adds headings and allows you to do multiple tests. [ruby] Benchmark.bm do |bm| bm.report('Test 1:') do 1_000_000.times do x = 1 end end bm.report('Test 2:') do 1_000.times do x = "Moo..." end end end # Example Output: #          user     system      total        real # Test 1:  0.430000   0.120000   0.550000 (  0.563787) # Test 2:  0.000000   0.000000   0.000000 (  0.000775) [/ruby] Then there is Benchmark.bmbm, which is exactly the same as bm, but preforms a benchmark twice. [source] Example Benchmark.bmbm Output: Rehearsal ------------------------------------------- Test 1:   0.370000   0.110000   0.480000 (  0.484865) Test 2:   0.000000   0.000000   0.000000 (  0.000529) ---------------------------------- total: 0.480000sec user     system      total        real Test 1:   0.390000   0.090000   0.480000 (  0.477402) Test 2:   0.000000   0.000000   0.000000 (  0.000529) [/source] And that is all there is to know about simple benchmarking, on to profiling. Profiling Profiling takes benchmarking to the extreme. It tells you how much time each part of your code is take, and all you have to do is put: [ruby] require 'profile' [/ruby] at the top of your program! [ruby] require 'profile' class MyMath # Don't worry about the math, just the profiling output # We repeat the code to make it use up more time def self.x_offset angle, distance 1000.times { distance * Math.sin(angle * Math::PI/180) } end def self.y_offset angle, distance 1000.times { distance * Math.cos(angle * Math::PI/180) * -1 } end end MyMath.x_offset(220, 50) MyMath.y_offset(220, 50) [/ruby] And from the profiling output, we can see what took the longest: [source] %   cumulative   self              self     total time   seconds   seconds    calls  ms/call  ms/call  name 72.41     0.21      0.21        2   105.00   145.00  Integer#times 10.34     0.24      0.03     4000     0.01     0.01  Fixnum#* 6.90     0.26      0.02     1000     0.02     0.02  Math.cos 6.90     0.28      0.02     2000     0.01     0.01  Float#/ 3.45     0.29      0.01     1000     0.01     0.01  Float#* 0.00     0.29      0.00        1     0.00   140.00  MyMath#y_offset 0.00     0.29      0.00        1     0.00   150.00  MyMath#x_offset 0.00     0.29      0.00        1     0.00     0.00  Class#inherited 0.00     0.29      0.00     1000     0.00     0.00  Math.sin 0.00     0.29      0.00        2     0.00     0.00  Kernel.singleton_method_added 0.00     0.29      0.00        1     0.00   290.00  #toplevel [/source] And that is it for today's episode! Please do not forget to show your appreciation by donating. If you have any thing to say about anything related to Man With Code or these videos, please leave a comment below, or email me at [email protected] Thanks for watching, Bye!
Keep reading...

Programming With Ruby Episode 15, Error Handling

Series: Ruby Programming

Covered in this Episode:
  • What are errors
  • What is error handling
  • begin...end
  • rescue
  • ensure
  • raise
Transcript: Hello Everybody and welcome to Programming With Ruby Episode 15, Error Handling. I'm Tyler and this video is brought to you by manwithcode.com. In this episode you will learn what exactly errors are, and what error handling is. You will also be learning how to use the begin...end, rescue, and ensure keywords, as well as the raise method. Lets get started! What are Errors? There are two types of problems with programs. #1 is bugs, and #2 is errors. You've most likely heard of both of these types of problems before. But what are they? Bugs are more subtle problems, the program still runs and acts normally, but it may be outputting the wrong data, or messing something else up. It is completely up to the programmer to find these bugs. Errors actually stop the program from running, or at least running all the way through. There are ways of handling most types of errors, which you will be learning about in this episode. What is error handling? It is possible to catch some types of errors, which when left alone, would otherwise result in your program crashing. Error handling is the process of catching those errors, and usually doing something about them, like informing the user, or executing on a contingency plan. There are many things that can create errors, such as trying to read from a file that doesn't exist, a user entering bad data, trying to call a method that does not exist, and the list goes on. Some errors you can combat by using methods like File.exists? to check if a file exists before trying to open it. But there are other cases where this is not an option, or where you prefer to handle the problem a different way. In this episode I will show you how. Real Code Error handling starts with the begin...end block which looks like this: [ruby] begin # Code here end [/ruby] In that block is where you put the code that has the possibility of generating an error. That block in itself doesn't do anything, to actually handle the errors, you need to use the rescue keyword. [ruby] begin # Possibly error inducing code here rescue # What to do if an error happens end [/ruby] What ever is between "rescue" and "end" will be executed if an error occurs. But what if you have the potential for multiple errors? Then you must use multiple rescues specifying the error the handle: [ruby] begin # Possibly error inducing code rescue ArgumentError # If ArgumentError is raised rescue NoMethodError # If NoMethodError is raised end [/ruby] What if you don't know the exact name of the error? Either create the error yourself and look at the output when the program crashes. Go to http://ruby-doc.org and find all classes ending Error. Or consult http://www.zenspider.com/Languages/Ruby/QuickRef.html#34 Now lets say you want something to happen regardless of whether or not the code generates an error. Say maybe you have to close a file, or end your connection to a database. Then you would want to use ensure! [ruby] begin # ... rescue # ... ensure # This gets executed no matter what end [/ruby] Now that you know how to handle errors, how do you go about raising errors of your own? With raise, of course! [ruby] def mymethod data if data.is_malformed? raise ArgumentError end end [/ruby] Why would you want to do this? It can serve as a better reminder to you or other programmers using your code that what they were doing is wrong. This can help stop bugs. This brings us to the end of the episode. If you have any questions, comments, or suggestions about anything related to Man With Code or these video tutorials; Please leave a comment below, or email me at [email protected] Do not forget to donate. A lot of time and hard work went into making these. If you liked these videos the best way to show your appreciation is by donating. Thanks for watching, goodbye!
Keep reading...

Programming With Ruby Episode 13, Basic I/O

Series: Ruby Programming

Covered in this Episode:
  • Defining I/O
  • Files
  • Directories
Transcript: Hello Everybody and welcome to Programming With Ruby Episode 13, Basic input output. As always, I'm Tyler and this video is brought to you by manwithcode.com In this episode I will be defining what exactly input/output is, You will also learn how to work with files and directories in Ruby Lets get started! Defining I/O So what exactly is I/O or input/output. Basically Input is any data that you receive from the user, and output is what data you give to the user, usually based on what input the user gave you. In this episode you will be seeing I/O as working with files and directories. You have already worked with I/O previously when we talked about getting strings from the user (gets) and printing string to the screen (puts) Files There are a couple of ways to start working with files. The first is by using File.new: [ruby] my_file = File.new('file', 'r') my_file.close [/ruby] File.new opens the file (the first parameter), for the specified mode (the second parameter) The file name you use can be either just the relative file name (notes.txt) or the full path to the file (C:\Documents and Settings\Tyler\My Documents\notes.txt). Just remember that if you use only the file name, that file must be in the same folder your program is located in! The mode defines how you are going to use the file you've opened. In the example 'r' is used. Which stands for read, meaning we are only going to read from the file. 'w' is write meaning we are writing to the file specified, be careful when using write mode, as the whole file is cleared when it is opened. 'a' is append, which is similar to write, except instead of clearing the whole file, it appends all written data to the end. All the different modes can have '+' at the end of them, which opens up both read and write functionality. (ex: 'w+') Now you know how to open a file, how exactly do yo go about writing to it? By simply using puts and print, like you did when outputting data to the screen, except they output data to the file! [ruby] my_file = File.new('example.txt', 'w') my_file.puts "Hello World!" my_file.close [/ruby] If you want to read from a file you can use File.read: [ruby] my_file = File.new('example.txt', 'r') puts my_file.read my_file.close [/ruby] You can also pass in how many characters you want to read as a parameter. If you would rather have the lines of a file in an array, you can use file.readlines. If you are unsure a file exists you can simply use File.exists?: [ruby] File.exists("notes.txt") [/ruby] Now it is important to note that every time I am done using a file I call the .close method, why do I do this? Because if you don't close your access on the file, it can become unusable by other programs. Also, your computers operating system might not write the changes you've made to the file, until your program has released its hold on it. As an alternative to using file.close every single time, we can use File.open, instead of File.new. File.open lets us use the file in a code block, at the end of the code block, the file is closed automatically. [ruby] File.open('hello.txt', 'w') do |file| file.puts "Hello World!" end [/ruby] There is a whole lot more you can do with files in Ruby to learn more go to http://ruby-doc.org/core-1.8.7/index.html and find the File and IO class Directories You can work with directories (also known as folders) in Ruby using Dir. You can create directories with Dir.mkdir: [ruby] Dir.mkdir("Hello") [/ruby] You can get an array of all the files and directories that are in the current directory with Dir.entries: [ruby] Dir.entries('.') [/ruby] Keep in mind that . is your current directory, and .. is the directory one level above the current one. Also, like files you can specify the relative path or the full path. There is also another method similar to Dir.entries, Dir.foreach. They are essentially the same, except foreach allows you to iterate over each item in a code block. [ruby] Dir.foreach('.') do |entry| puts entry end [/ruby] Like Files, there is a lot of material I couldn't cover to learn more go to http://ruby-doc.org/core-1.8.7/index.html and find the Dir class This brings us to the end of the episode. If you like these videos please donate. And if you have any Questions, Comments or Suggestions, you can leave a comment in the comment box below, or email me at [email protected] Thank you very much for watching, goodbye.
Keep reading...

Programming With Ruby Episode 9, Flow Control

Series: Ruby Programming

Part 1: Part 2: Covered in this episode:
  • Code Blocks
  • if, else, unless
  • case, when
  • while, until, for loops
Transcript: Hello everybody and welcome to Programming With Ruby Episode 9, Flow Control. I'm Tyler and this video is brought to you by manwithcode.com So far all of the programs and code that I have shown you has been completely linear. There has been no way to loop based on a condition or do something based on what the user inputs. In this episode I will be showing you how to do all this, and I will also be explaining to you what a code block is, since I've been mentioning them in almost every episode previous to this. This episode is REALLY LONG! Feel free to pause the video and think about what's been said or try out code yourself. Code Blocks Throughout the previous videos, I've been telling you about code blocks, I've also been telling you I'll teach you what they are in a later episode. That episode has finally come. Code blocks look something like this: [sourcecode language="ruby"] my_array.each do |item| puts item end [/sourcecode] or like this: [sourcecode language="ruby"] my_array.each { |item| puts item } [/sourcecode] Both of those actually do the same thing! The .each method takes a block as an argument. The block is what is between the do and end keywords, or the curly braces, depending on which format you use. The item between the pipe characters (which is above the ENTER key) is the variable the .each method gives you (in this case the item in the array). The rest of the code block is just normal Ruby code. Not so complicated, eh? (Keep in mind that there are more metheds besides .each that take code blocks) If, Else, and Unless A basic if statement would look like this: [sourcecode language="ruby"] x = 3 if x < 5 # Do something end [/sourcecode] The "x < 5" is the condition that has to be true for the code to run. If that condition is true, the code between the "if" and "end" keywords is run. There are many different conditional operators you can use: [sourcecode language="ruby"] == < > <= >= != [/sourcecode] Just be sure to keep in mind that the "is equal" operator uses two equal signs, not one. If you would like code that is run when the condition is false: [sourcecode language="ruby"] x = 3 if x < 5 # Do something if true else # Do something if false end [/sourcecode] In a similar way you can execute code if the first condition is false but a second is true: [sourcecode language="ruby"] x = 3 if x < 5 # Do something if true elsif x == 3 # Do something if the first is false and this is true else # Do something in all are false end [/sourcecode] In a different way you can only execute the code if two conditions are true: [sourcecode language="ruby"] x = 3 y = 2 if x == 3 and y == 2 # Do something end [/sourcecode] You can also only execute code if one of any conditions are true: [sourcecode language="ruby"] x = 3 y = 4 if x == 3 or y == 2 # Do something end [/sourcecode] There is also the evil twin brother of if, unless: [sourcecode language="ruby"] x = 3 unless x == 3 # if x is 3, this code will not run end [/sourcecode] You can chain all of these together in almost any way you choose. Case, When Another way to evaluate conditions is using case, when: [sourcecode language="ruby"] x = 3 case x when 1 then # do something when 3 then # do something else # do something if none are true end [/sourcecode] You can't do many complex conditionals, but it can be nicer than a long chain of if, else's while, until, and for loops Similarly to the above if statements, while, until, and for loops will execute code based on a condition, but they will do it multiple times. while: [sourcecode language="ruby"] x = 1 while x < 5 x += 1 puts x end [/sourcecode] Similar to the relationship between if, and unless. while has an evil sister, until [sourcecode language="ruby"] x = 1 until x > 5 x += 1 puts x end [/sourcecode] There are also for loops, which allow you to iterate over something [sourcecode language="ruby"] foods = ["ham", "eggs", "cheese"] for food in foods puts food += " is yummy!" end [/sourcecode] There is also .each, for's evil stepchild: [sourcecode language="ruby"] foods = ["ham&", "eggs", "cheese"] foods.each do |food| puts food += " is yummy!" end [/sourcecode] Concrete Example A menu system [sourcecode language="ruby"] input = "" until input == 'quit' puts " Menu (1) Hi! (2) Credits (3 or quit) Exit " input = gets.chomp! case input when "1" then puts "Hi!" when "2" then puts "Written By: Tyler" when "3" then input = 'quit' else puts "Invalid input" end end [/sourcecode] Lets break it down. First we set the input variable to an empty string (so the second line dosen't give us an error) Then we use an until loop that quits when input is equal to 'quit' Next we print the menu (which is unindented so it doesn't print to the screen indented) After that we get input from the user, use .chomp! to remove the newline character created from pressing ENTER, and put the input into the input variable Then we have a case statement, when "1" we print "Hi!", when "2" we print who it was created by, when "3" we quit, otherwise we print out "Invalid input" to tell the user they entered something wrong. This brings us to the end of the video. If you like these videos please donate, because I'm doing this all for free If you have any questions, comments, or suggestions, you can leave a comment on this page. Or you can email me at [email protected] I covered a lot of material in this episode and I urge you to watch it again, go to the original post and look at the code (link is in the description) and write some code yourself. Thank you very much for watching, goodbye!
Keep reading...

Programming With Ruby Episode 8, Hashes

Series: Ruby Programming

Covered In This Episode:
  • What are Hashes?
  • Hash Creation
  • Hash Accessing
  • Hash iteration
  • Hash Methods
Transcript: Hello Everybody and welcome to Programming With Ruby Episode 8, Hashes. I'm Tyler,and this video is brought to you by, manwithcode.com In this episode I will be telling you what hashes are, how you can create them, access them, and iterate over them. Finally at the end I will show you some useful methods that hashes have. What Are Hashes? Hashes are like arrays, which you learned about in the previous episode. Except that they have no order, and instead of being accessed by an index number, they are accessed by what is called a key (which can be anything). That key points to a value, which is the actual data inside the hash Arrays are used for lists of data, where hashes are used to relate data. I may have a hash where the keys are my friend's names, and the values are their birthdays. Hash Creation Similarly to how arrays are created with square brackets, hashes are created with curly brackets: [sourcecode language="ruby"] my_hash = {} [/sourcecode] Items are defined like this: [sourcecode language="ruby"] birthdays = {"Amy" => "May", "Dakota" => "January"} [/sourcecode] Each key-value pair are separated by a comma, and their relation is defined with => Accessing Hashes You can access hashes in almost the same way you access arrays, except by using the key value, instead of an index number: [sourcecode language="ruby"] brithdays["Amy"] #=> May [/sourcecode] You can define new keys and values: [sourcecode language="ruby"] birthdays["Zack"] = "April" [/sourcecode] Iterating Over Hashes Hashes have an each method like arrays do: [sourcecode language="ruby"] my_hash = {"cat" => "hat", "dog" => "log"} my_hash.each do |pair| puts "Key: " + pair[0] puts "Value: " + pair[1] end #=> Key: cat #=> Value: hat #=> Key: dog #=> Value: log [/sourcecode] They also have each_key and each_value which let you iterate over each key or value in a similar way. Useful Hash Methods delete(key) deletes a key-value pair empty? True or False if the hash is empty keys returns the keys values returns the values size how many key-value pairs there are That wraps it up for this episode! Please donate, or I will stop making these videos. There should be a link to donate to the right of this video. If you have any questions or comments leave a comment on this page or email me at [email protected] Thanks for watching, goodbye!
Keep reading...

Programming With Ruby Episode 7, Arrays

Series: Ruby Programming

Covered In This Episode:
  • What Aarrays Are
  • Array Creation
  • Accessing Arrays
  • Array Iteration
  • Other Array Methods
Transcript: Hello everybody and welcome to Programming With Ruby Episode 7, Arrays. I'm Tyler. And this video is brought to you by manwithcode.com In this episode I will be telling you what arrays are, how you can create an array in ruby. How to manipulate arrays by accessing them, iterating over them, and by showing you a few useful methods they have. Lets get started! What are Arrays? Arrays are a type of variable. Think of an array as a list. This list can hold anything, names, numbers, objects, anything. Objects in the array have a number, depending on what place they are in the list. Because computers start counting at 0, the first element in the array is 0, instead of one. Array Creation This is how a variable is defined in ruby: [sourcecode language="ruby"] x = [] [/sourcecode] This is an empty array, if we wanted an array with something in it: [sourcecode language="ruby"] todo_list = ["Cut Grass", "Buy Food", "Fix Tom's Computer"] [/sourcecode] Each bracket represents the start and the end of the array, respectively. Each item in an array is separated by a comma. Accessing Arrays Now that you have created an array, how do you go about accessing each item? I told you earlier that each item had a number, so to access the first item in the array you would do: [sourcecode language="ruby"] todo_list[0] #=> "Cut Grass" [/sourcecode] You can also add items to an array in a similar way [sourcecode language="ruby"] todo_list[3] = "Go Skydiving" [/sourcecode] Another way to add items is to use +=, which you may recognize from previous tutorials [sourcecode language="ruby"] todo_list += ["Eat Sandwich"] [/sourcecode] Don't forget that if you use += that the item your adding has to be between brackets You can also use ranges to access elements in the array. ranges are used in a similar way that you normally access arrays, except ranges look like this: [sourcecode language="ruby"] todo_list[0..2] #=> ["Cut Grass", "Buy Food", "Fix Tom's Computer"] [/sourcecode] The 0 is the start number and the 2 is the end number. you can also use -1, which is the end of the array: [sourcecode language="ruby"] todo_list[3..-1] #=> ["Go Skydiving", "Eat Sandwich"] [/sourcecode] Array Iteration If you want to loop over each element of an array you use the each method: [sourcecode language="ruby"] numbers = [1, 2, 3, 4] numbers.each do |number| puts number * 2 end #=> 2 4 6 8 [/sourcecode] You can do the same thing, but turn the output into an array with the collect method: [sourcecode language="ruby"] numbers = [1, 2, 3, 4] numbers.collect do |number| number * 2 end #=> [2,4,6,8] [/sourcecode] Other Array Methods Now I'm going to show you some useful methods arrays have! empty? tells you if an array is empty sort sorts the array (alphabetically) reverse reverses the array delete deletes a specified item from the array delete_at deletes whatever is at that index in the array find finds an item with the specified value inspect returns the way an array looks in code, instead of its values, this is useful for puts my_array.inspect length how long the array is That's it for today's episode Please don't forget to donate, the link should be to the right of this video If you have any questions or comments, leave a comment on this page or email me at [email protected] Thanks for watching, bye!
Keep reading...

Programming With Ruby Episode 6, Strings

Series: Ruby Programming

Covered in this episode:
  • String Literals
  • String Expressions
  • String Methods
  • Regular Expressions
  • Getting User Input (gets)
Transcript: Hello Everyone and Welcome to Programming With Ruby Episode 6, Strings. I'm Tyler, your presenter. This is brought to you by manwithcode.com In this episode I will be telling you what string literals are. I will show you expressions you can use with strings, which are similar but still different than expressions with numbers. I will show you useful methods strings have. I will show you how to use regular expressions. Finally I will teach you how to get input from the user. On to the Code! String Literals According to wikipedia, string literals are the representation of a string value within the source code of a computer program. For example: [sourcecode language="ruby"] puts "Hello World" # Hello World is the string literal [/sourcecode] String Expressons The only string expressions are the plus and multiplication sign. The plus sign connects strings together, the multiplication sign repeats a string a certain number of times. Let me show you how it works: [sourcecode language="ruby"] "Hello " + "World!" #=> "Hello World!" "Hello " * 3 #=> "Hello Hello Hello" [/sourcecode] String Methods Here are some useful String methods: empty? tells you if you are dealing with an empty string length tells you how long a string is each_char lets you iterate over each character capitalize capitalizes the first character upcase makes all characters upper case downcase makes all characters lower case Regular Expressions Regular expressions are a way to match elements in other strings. It is easier to show you than to describe to you, so here we go! The simplest is substitution: [sourcecode language="ruby"] "Hello World".sub("Hello", "Goodbye") #=> "Goodbye World" [/sourcecode] But if you have more than one hello: [sourcecode language="ruby"] "Hello Hello Hello".sub("Hello", "Goodbye") #=> "Goodbye Hello Hello" [/sourcecode] This happens because the sub method only replaces the first occurrence of "Hello". The gsub method fixes this: [sourcecode language="ruby"] "Hello Hello Hello".gsub("Hello", "Goodbye") #=> "Goodbye Goodbye Goodbye" [/sourcecode] What if you want to manipulate parts of a string using regular expressions. The scan method is what you want! [sourcecode language="ruby"] # /n means new line "Who are you".scan(/../) { |x| puts x } #=> Wh\no \nar\ne \nyo # With no whitespace: "Who are you".scan(/\w\w/) { |x| puts x } #=> Wh/nar/nyo [/sourcecode] Regular Expressions are a vast topic that I can't completely cover here, so do a Google search to find out more. Getting User Input You can get user input with the "gets" method: [sourcecode language="ruby"] a = gets # The user inputs: I like pie puts a #=> "I like pie" [/sourcecode] That wraps it up for todays episode. Don't forget to donate, the link is to the right of this video If you have any questions or comments, leave a comment on this page or email me at [email protected] Bye!
Keep reading...

Programming With Ruby Episode 5, Numbers

Series: Ruby Programming

Covered in This Episode
  • Numbers
  • Expressions
  • Types of Numbers
  • Constants (New type of variable!)
  • Doing something a number of times
Transcript Hello Everyone and Welcome to Programming With Ruby Episode 5, Numbers. Its sitll presented by me, Tyler. And brought to you by manwithcode.com In this episode I will be talking about numbers in Ruby. I will go over expressions, the different types of numbers, I will introduce a new variable type called a constant, and will show you how to repeat an action a certain number of times in Ruby. Lets get started! Pop open you Command prompt or Terminal and start Interactive Ruby. If you have forgotten, just enter 'irb'. First item is expressions. [sourcecode language="ruby"] 2 + 2 #=> 4 2 - 2 #=> 0 3 * 3 #=> 9 6 / 3 #=> 2 2 ** 5 #=> 5 [/sourcecode] expressions with variables work in the same way [sourcecode language="ruby"] x = 5 5 * x #=> 25 x ** 4 #=> 625 [/sourcecode] If you want to do math on a variable and set the value of the variable to the result use: [sourcecode language="ruby"] x = 5 x *= 2 #=> x = 10 x -= 4 #=> x = 6 x /= 6 #=> x = 1 [/sourcecode] In Ruby there are 3 different types of numbers. Fixnum, which are 32-bit numbers. Floats, which are numbers with a value after the decimal point. Bignums which are numbers larger than 32-bits. [sourcecode language="ruby"] 5.class #=> Fixnum 0.421.class #=> Float 999999999999 #=> Bignum [/sourcecode] In Ruby it is possible to separate up larger numbers to improve readability in the code. Simply place in underscores [sourcecode language="ruby"] 1_000_000 #=> 1000000 [/sourcecode] Lets say you are writing some code and you need to do something a certain number of times. Use this code: [sourcecode language="ruby"] 2.times do |x| puts x end #=> 0 #=> 1 [/sourcecode] That wraps it up for this episode. If you have any questions or comments, leave a comment in the comment box below. Or email me at [email protected] Don't forget to donate. The button is to the right of this video. Thanks for watching. Goodbye
Keep reading...

Programming With Ruby Episode 4, Main Ruby Concepts

Series: Ruby Programming

Covered In This Episode:
  • Basic Variables
  • Basic Methods
  • Basic Classes
  • Interactive Ruby (irb)
Code: [sourcecode language="ruby"] # Define the class Greeter class Greeter # Define the method hello # This method greets the # user def hello(name) puts "Hello " + name end # End of the method hello end # End of the class Greeter Greeter.new.hello("Tyler") [/sourcecode] Transcript: Hello everybody and welcome to Programming With Ruby Episode 4, Main Ruby Concepts. Covered in this episode. We'll be playing with interactive ruby (also called irb). I will teach you about variables, basic methods, and classes in Ruby. Lets get started! Basics Description Ruby is an object oriented programming language. object oriented languages use objects. Ruby goes beyond most other object oriented languages, because in Ruby, everything is an object. (I'll show you exactly what that means in a few minutes) Object oriented programming sort of models real life. Look around you, everything around you is an object. Your computer, your desk, books, the moon, and people are all objects. In programming, all objects have properties called variables. These could be the color of the object, the weight, size, or any other kind of property. Objects also have methods (which are sometimes called functions). A camera object would have a method to take pictures. A car would have a method to drive. A printer would have a method to print. As well as making code easier to understand, you will also continue to appreciate other benefits of object oriented programming further on in your programming career. Example I have written a very basic Ruby program. This is about what most programs look like, just a lot simpler. Let's break it down line by line. Everything followed by a hash mark (#), is ignored by Ruby. These are called comments. In these comments you can describe what your code is doing, make notes to yourself, and other such things. The first line says "class Greeter". This line tells Ruby that we are now defining a class named "Greeter". Please remember that all classes in Ruby start with a capital letter! The next line says "def hello(name)". This line means we are defining a function (def), named "hello", that takes the parameter "name". The following line is a little trickier. 'puts "Hello " + name'. "puts" means "put string". our string is "Hello " + name. Now you're probably wondering what the "+ name" is for. We're aren't doing math on strings, but we are connecting the variable "name" to our other string "Hello ". The next two lines have the keyword "end". The first end means we are done defining the function "hello". The second "end" means we are done defining the class "Greeter". Below where the class "Greeter" ends we have the line 'myname = "Tyler"'. This means are creating the variable myname and placing "Tyler" inside of it. Next is, the line "person = Greeter.new". This means we are instantiating a new greeter object named person. Finally we have the line "person.hello(myname)". This calls the person object's method "hello" and passes the variable "myname" as an argument. Now lets run the program. If you remember, to run a program you open Terminal or Command Prompt, change directories into where you saved your program and type "ruby programname.rb". In my case I will type "ruby episode4.rb". And there you have it, it says "Hello Tyler" The code in this example will be available in the YouTube video description, and below this video on manwithcode.com Example 2 Back to the code. This code is actually a little longer than it has to be. I did this so things would hopefully make more sense. In reality we can change the last three lines to 'Greeter.new.hello("Tyler")' We can do this because in Ruby, everything is an expression. Here's how it breaks down. "Greeter.new" creates a greeter object. ".hello" calls the method "hello" on that new object. And then we pass in the string "Tyler" as an parameter. Ruby has many other tricks like this to make your code shorter. Some have disadvantages and others do not. One of the most important disadvantages can be clarity or readability. You want your code to be as easy to understand as possible. irb Interactive Ruby (or irb for short). irb makes it very easy to quickly test out code, find out if/how something works, do basic math, and write throwaway code you will only use once. To open irb, open up your Command Prompt or Terminal and enter irb. Alternatively, if you are on Windows, go into All Programs and under Ruby will be a program name fxri which is an equivalent to irb. In irb you can do basic math: [sourcecode language="ruby"] 2 + 2 #=> 4 2**6 #=> 64 2 * 5 #=> 10 [/sourcecode] We can write any valid Ruby code. So we could write the greet method again. [sourcecode language="ruby"] def greet(name) puts "Hello " + name end [/sourcecode] And then call it: [sourcecode language="ruby"] greet("Tyler") [/sourcecode] Remember earlier I said everything in Ruby was an object? I'll show you what I mean. if you type in the name of an object and call the class method it will tell you its class. [sourcecode language="ruby"] 0.class #=> Fixnum "Hello".class #=>; String String.class #=> Class [/sourcecode] I encourage you to play around with irb for a little while, try writing your own methods, and have some fun with it. End This brings us to the end of this episode, I hope it helped you.  If you need any help, have questions or comments, leave a comment below or contact me at [email protected] Don't forget to donate! There is a donation link to the right of this video. On YouTube its in the description box. On my website, it is to the right of the video. Thanks for watching! Bye!
Keep reading...

Programming With Ruby Episode 3, Getting Help/Tools

Series: Ruby Programming

Covered in this episode:
  • How to get help
  • Google
  • Ruby's Documentation
  • Forums/Mailing Lists
  • Blogs on Ruby
  • Text Editors
  • Integrated Development Environments (IDEs)
Links: Ruby-Lang: http://www.ruby-lang.org Ruby-Doc:  http://www.ruby-doc.org/ Forums: http://www.ruby-forum.com/ http://www.rubyforums.com/ Text Editors: Notepad++ http://notepad-plus.sourceforge.net/uk/site.htm SciTE http://www.scintilla.org/SciTE.html jEdit http://www.jedit.org/ Text Mate http://macromates.com/ IDEs Netbeans http://www.netbeans.org/ Aptana Rad Rails http://www.aptana.com/ FreeRIDE http://rubyforge.org/projects/freeride/ Geany http://www.geany.org/ More... http://rubyforge.org/softwaremap/trove_list.php?form_cat=65 Transcript Hello Everybody! And Welcome to Programming with Ruby Episode 3, Getting Help and Tools. I'm your presenter, Tyler. This video is brought to you by manwithcode.com Covered in this Episode. I'll be going over how to get help. If you ever get stuck while using Ruby you're first stop should be Google, to some this may sound obvious, but some people still don't use Google. Your next stop would be Ruby's Documentation. Then I will be showing you forums and mailing lists where you can ask for help or help others. Also I will be showing you some blogs by Ruby Developers. On the tools side, I will be showing you some good Text Editors, and a few IDEs (or Integrated Development Environments). Just as a side note, I will be showing many websites today, but don't worry, all links are in the description Lets Get Started! Out first stop will be Google. Lets say I wanted to learn about Ruby Lambdas just type in "ruby lamdas" and you get a list of relavant web pages. I'll pick the first link, and here is some information on how to use lambdas. If Google can't help you, lets look at the official Ruby Documentation. This is ruby-doc.org. It has some articles and tutorials on Ruby. But what we are interested in is the part that says "Core API" we are using the 1.8 version of Ruby, so we will visit the 1.8.6 core link and here is the documentation for Ruby! lets say I wanted to look for lambdas again, I'll hit CTRL-F for the browsers find funtion, and type in "lambda" and here is the information I want, I'll click the link, and there is the documentation! Okay lets say that a Google search and a look through the documentation doesn't help you with your problem. What do you do? You ask a person, of course! This is where the forums come in. There are two forums that I like, there is ruby-forum.com And rubyforums.com both of which you can post on and will hopefully get answers For general tips and news about Ruby, you may be interested in some blogs about Ruby. To find some, lets go to ruby-lang.org click on the community link. scroll down, and click the "weblogs about ruby" link and here there are some blogs, and aggregators listed So hopefully if you have a problem all these resources should be able to help you. Now we are going to move onto tools. First stop Text Editors. There are a few good text editors available, so I will just highlight a few. If any of these look interesting, remember that all links are in the description. First is Windows only text editor notepad++, the editor I use on Windows Then is SciTE, a scintilla based editor Jedit is a popular text editor that is written in Java Text mate is a very popular text editor for the Macintosh that costs $55 For Linux there are editors like gEdit and Kate which have some of the features of the editors mentioned above. Even if you like your featureless plain text editor like notepad, features the previously mentioned editors have make writing code much easier, and I recommend you get one. First we have netbeans, which is my IDE of choice. Even though it was originally for Java, it works very well with Ruby Next is Aptana rad rails, an IDE which many people like, but was too buggy on my computer, it is especially useful if you are using Ruby on Rails freeRIDE is a popular editor for ruby Geany is a GTK based editor for Linux that works with many different languages These are all very good editors, but because you are currently learning I would just recommend a text editor for now, when you start developing larger projects an IDE can be very useful. This brings us to the end of this episode, I hope it helped you. If you need any help, have questions or comments, leave a comment below or contact me at [email protected] Hey! before you go, you may have realized that I am making these videos for free if they have helped you at all please donate. If you viewing this on Youtube there is a donation link to the right in the description box. If you are on my site there is a donation button to the right Thanks for watching! Bye!
Keep reading...

Programming With Ruby Episode 1, Introduction

Series: Ruby Programming

Covered in this episode:
  • What this series is about
  • A Short History of programming languages
  • What is Ruby (and who makes it)
  • What is Ruby used for
  • Who am I
  • Why am I teaching this
Transcript Hello everybody and welcome to Programming with Ruby Episode 1, Introduction What this series is about By the end of this series you should be able to effectively use the programming language, Ruby Short History of Programming Languages when it all first started out, everything was just 1s and 0s, it was hard to use, and difficult to debug then it got a little better when assembly came along. You had words like MOV that translated into the corresponding 1s and 0s. compiled by and assembler then came COLBOL and FORTRAN then C, which was better, but still sucked then C++ which brought object orientation to the world then Python and Ruby. they are both object oriented and very easy to use. What is Ruby? A programming language, that supports many different kinds of programming paradigms, and is fully object oriented Ruby was created by Yuukihiro "Matz" Matsumoto Matz designed Ruby to be natural, not simple. I think he achieved that. What is Ruby Used For? Ruby is used a lot for Web Applications Computer Administration Task Automation Game Programming And almost anything else The only thing you might want to stay away from are things that are computationally expensive, like image processing. Who am I? I am Tyler J Church I run the sites Man With Code (manwithcode.com) and ruby game dev (rubygamedev.wordpress.com) Why am I Teaching This? It is the tutorial I never had. I was look for something like this when I started learning Ruby. I didn't want to read a bunch, I wanted to watch videos, but nothing like that existed I think video is the best way to learn I want to give back to the community. That brought me Ruby, that helped me learn. Thank You! Questions or Comments Leave a comment on this page or email me at [email protected] Thanks for reading!
Keep reading...

Ruby Programming Series Announced

I am announcing that the first tutorial series will be on Ruby Programming! Outline for the Ruby Tutorial
Keep reading...