Ruby programming
Ruby is the programming language used for the back-end application logic in Anki Books. Ruby is a really sharp language and also very gentle (like Python's sister) used mostly for web development (Python is used for everything).
Local variables
Variables are pretty fundamental to programming, so I guess we start with them. This is what it looks like to assign a variable:
my_first_v = 1
This creates an identifier in the scope of the current object, which is an object called main if you're just writing a script.rb file to declare variables. It is a local variable called my_first_v that references an object in memory which is essentially data representing the number 1. If we do this:
my_first_v = 2
Now my_first_v references (or "points to") a different object in memory that represents the number 2. The first object that represented 1 can be collected out of the heap of memory being used by the garbage collector when it is detected that it is not needed anymore.
"Everything is an object in Ruby"
Variables are references to objects. In Ruby, everything is an object including data (there are exceptions to "everything is an object in Ruby" such as block arguments). The different types of data in Ruby such as numbers, strings, and lists (called arrays in Ruby) of data are all different types of objects. The type of an object is a class. An actual instance of a class is called an object. An object in Ruby has some internal private data as instance variables and a reference to its class which defines the methods that the class uses to respond to messages and operate on that private data. Variables are usually named to carry some useful information about the objects they reference. In Ruby, names of local variables should be snake_case.
Constant variables
Identifiers or names in the program that begin with a capital letter are constants and that includes the names of modules, classes, and constant variables. Constant variables are usually named using all capital letters but technically you can just start them with one capital letter. Static analysis of Ruby code where a constant variable is named like that would probably issue a warning.
String data type
str = "hello world" num = 10
Common mistake: typing = instead of ==
If you are new to programming, take note that = is assigning a value to a variable; it is not comparing for equality like in algebra. == can be used to compare for equality in Ruby and it is a common mistake to type = instead of == in many different programming languages.
Declaring vs instantiating a variable
Declaring a variable in programming usually involves specifying a name and a type for the variable. With Ruby we do not need to specify a type and we can initialize or instantiate the value of the variable at the same time. Even in languages where you can declare a variable and initialize it later, it is best to give it a value as soon as it is declared. It is also good to declare variables as late as possible most of the time and in the tightest scope of the program that they are needed. Note that although we do not declare a type for the variable in Ruby, the object itself does have a reference to its class and therefore does have a type. The variable name can be reassigned to point to a different object and that new object does not have to be the same type as the previous value.
Methods
Methods in Ruby are defined using the def keyword. Methods take a number of named variables called parameters. The data objects that are called with the method and at the same time assigned to those parameters are called arguments. Sometimes people do not care about the difference so you might hear them used incorrectly.
Classes
Classes in Ruby are basically templates for creating objects. Instances of a class are generally called objects. When an object is created, it is given some initial data and a reference to its class which defines the expected data (as instance variables) and also the behavior (as methods). Instance variables are the variables in Ruby that start with @. It may be a good idea to always expose instance variables through a getter and setter even when using the instance variable inside the class where it is accessible without those. A quick way to create getters and setters in Ruby is with the class methods attr_reader, attr_writer, and attr_accessor that take the symbol name of an instance variable as an argument.
Example: Ruby block argument
Given "there is a user with username {string}, email {string}, and password {string}" do |string, string2, string3| User.create!(username: string, email: string2, password: string3) end
In Ruby, there are 3 types of closures to know, and the main one to know is the block argument. The block argument to a method in Ruby is a closure because it captures all of the local artifacts in its environment and carries them into the method call. This means that inside the method call that receives a block argument, it can execute the code of the block argument it receives inside of its internal implementation. I would recommend anyone take some time and compare the Gherkin statements to the step definitions, even if you do not code because it is the fundamental thing to understand about Cucumber. The main thing that Cucumber lets you do is have executable documentation that stays up to date because it is a runnable test suite, and it also allows anyone on the team write technical documentation/specify a new feature. Cucumber is a tool related to the behavior-driven development approach where the program is specified outside-in rather than inside-out which would be more like test-driven development where you write unit tests first.