WHIRLWIND OVERVIEW OF THE RUBY LANGUAGE

The "R" in RGSS

  • kentona
  • 07/29/2010 03:50 PM
  • 13319 views

In an effort to try to understand the scripting language behind Ruby Game Scripting System 2 (RGSS2) I breezed through a quick online tutorial on Ruby (which you can find here). For my sandbox, I downloaded the Ruby Installer for Windows from here, and ran the Interactive Ruby program.

I am familiar with languages like C/C++, Visual Basic and Java so I didn't anticipate any issues with going through the basics of Ruby programming. This is the first time I have ever used the language, so forgive me if I get anything wrong.

Without further ado, here are the basics of Ruby.

WHAT IS RUBY? ::..
Ruby is an object-oriented interpreted scripting language. That is, Ruby code is run through an interpreter at run-time, compiled and executed. Contrast that with a language like C++ where code must be linked and compiled into an executable before it can be run.

Object oriented languages typically make use of classes (that act as a template) and instances of a class (called objects) which you can manipulate with methods. Ruby is no exception here.

COMMENTS ::..
Lines prefixed with # are commented out and are not run by the interpreter

#This is a comment

=begin
This is a
multiline
comment
=end


VARIABLES ::..
Ruby uses dynamically typed variables (meaning that the variable type is determined by the interpreter at run-time and you do not have to explicitly state that the variable you are defining is a String or an Integer, like in other languages like Java or C++). Thus it is sufficient to write myVariable = "Hello World!" and the interpreter knows that myVariable is an object of the String class.

Name Begins With	Variable Scope

$ A global variable
@ An instance variable
[a-z] or _ A local variable
[A-Z] A constant
@@ A class variable


Examples:
$globalvar = "This can be accessed anywhere in the program!"
@@isShared = "A variable that is shared amongst all instances of a class."
@classdata = "This value is local to specific instance of an object."
localStuff = "The scope of this will be limited to the block of code it is in, like a method"
MYCONSTANT = "Surprisingly, constants can be modified in Ruby!"

Special variables:
nil null value (uninitialized)
self refers to the currently executing object

Operator	Description

+ Addition - Adds values on either side of the operator
- Subtraction - Subtracts right hand operand from left hand operand
* Multiplication - Multiplies values on either side of the operator
/ Division - Divides left hand operand by right hand operand
% Modulus - Divides left hand operand by right hand operand and returns remainder
** Exponent - Performs exponential (power) calculation on operators

Note that when performing division, if you do not want the result to be truncated to a round number, one of the operands in the operation must be expressed as a float.

Also, all the operators can be combined with an assignment operator:
x += y #same as x = x + y
x *= y #same as x = x * y
..etc..

a, b = b, c #Parallel assignment is also useful for swapping the values held in two variables


Bitwise operators (since all data is stored as bits like 10010110 these operators can manipulate data at the bit level)

~ Bitwise NOT (Complement)
| Bitwise OR
& Bitwise AND
^ Bitwise Exclusive OR
<< Bitwise Shift Left
>> Bitwise Shift Right



RANGES ::..
Used to define a sequential range of values

.. defines an inclusive range
... defines an exclusive range

numbers = 1..10 #defines a collection of numbers of 1 to 10
words = 'cab'..'car' #defines a collection of strings from cab to cac to...caq to car

words.include?('can') # check to see if a value exists in the range


ARRAYS ::..
A collection of variables stored in a self-contain object. Array indexes start counting at 0 (thus the first element in an array is indexed at 0)

blah = [ "b", "l", "a", "h"] #define an array
blah[2] #access an individual element 'a'
blah[1,2] #starting index, number of elements
blah[0..2] #range
blah << "!" #elements can be appended using <<
myList.uniq #no duplicate elements
myList.uniq! #remove duplicate elements from the array
myStack.push "blarg" #arrays can be used like stacks (last in, first out)
myStack.pop #pop the last element off the stack
colors.insert( 1, "orange" ) #insert new elements at the given index
colors.delete_at(1) #delete the element at the given index
colors.delete("red") #delete a particular element
numbers.sort #returns a sorted array
numbers.sort! #sorts the array
numbers.reverse #returns a descending sorted array

Operator	Description

+ Concatinate two arrays
- Difference - Returns a new array that is a copy of the first array with any items that also appear in second array removed.
& Intersection - Creates a new array from two existing arrays containing only elements that are common to both arrays. Duplicates are removed.
| Union - Concatenates two arrays. Duplicates are removed.
== true if two arrays contain the same number of elements and the same contents for each corresponding element.
eql? same as == except that the values in corresponding elements are of the same value type.
<=> compares two arrays and returns 0 if the arrays are equal, -1 one if the elements are less than those in the other array, and 1 if they are greater.



HASH ::..
A Hash is a collection of key-value pairs. It is similar to an Array, except that indexing is done via arbitrary keys of any object type, not an integer index. The order in which you traverse a hash by either key or value may seem arbitrary, and will generally not be in the insertion order.

Hashes have a default value that is returned when accessing keys that do not exist in the hash. By default, that value is nil.

Hash["a", 100, "b", 200]
=> {"a"=>100, "b"=>200}

Access data in a hash by its key. If the key specified doesn't exist, the default is returned.

h = Hash.new("Go Fish")
h["a"] = 100
h["b"] = 200
h["a"] #=> 100
h["c"] #=> "Go Fish"
# The following alters the single default object
h["c"].upcase! #=> "GO FISH"
h["d"] #=> "GO FISH"
h.keys #=> ["a", "b"]



METHODS ::..
Methods are blocks of code (usually within a class) that performs some logic. They are defined with the def command and end with the end command.

def methodname(param1, param2)
...code...
end


Some examples can illustrate some variations:
#variable number of arguments

def displaystrings( *args )
...code...
end

#default argument
def blah(var = "Hello World")
...code...
end

#returns a value
def multiply(val1, val2 )
result = val1 * val2
return result
end



MODULES ::..
Modules are used for grouping similar methods and variables together under a familiar name. They are defined with the module command and end with the end command.


module Kenton

# variables
h = "Hello "
w = "World!"

def helloworld
puts h + w
end
end


I am not very familiar with modules since the tutorial didn't really cover it, which is unfortunate because VX scripts seem to be chock full of them. It does look like modules can be nested.


CLASSES ::..
Classes are blueprints or templates for objects in your code. It will often contain a list of member variables and methods.

When you create an instance of a class, you create an object. An object is a self-contained piece of functionality that can be easily used, and re-used as the building blocks for a software application. Objects consist of data variables and functions (called methods) that can be accessed and called on the object to perform tasks. These are collectively referred to as members.

class BankAccount

#public instance variables
attr_accessor :bankName
attr_accessor :bankNumber

#a class variable and its accessor (shared across all instances of this class)
def interest_rate
@@interest_rate = 0.2
end

#an instance variable and its accessor
def accountNumber
@accountNumber
end

#assignment method (for assigning new values to our instance variable
def accountNumber=( value )
@accountNumber = value
end

def accountName
@accountName
end

def accountName=( value )
@accountName = value
end

#constructor
def initialize(number)
@accountNumber = number
end

#a custom method to calculate interest
def calc_interest ( balance )
puts balance * interest_rate
end
end


You define new instances of a class by using the new method. You call methods within the class by using instance.methodname(parameters)

#local variable created as a new instance of the BankAccount class
account = BankAccount.new()
#call the calc_interest method on the account variable
account.calc_interest( 1000 )
=> 700.0


Note that Ruby supports single inheritance in that a subclass can only inherit from a single superclass. With inheritance, a child or subclass will have access to all the methods and instance variables of its parent, plus whatever new ones you define.
#include statement in Ruby, if the BankAccount class is in a different file

require 'BankAccount'

class NewBankAccount < BankAccount

def customerPhone
@customerPhone
end

def customerPhone=( value )
@customerPhone = value
end

end



FLOW ::..
These commands control logical flow through the code. Things like if and elsif and case and unless statements evaluate an expression and execute a block of code if the expression evaluates to true. Things like while and until and for loop through a block of code until exit conditions are met.

if expression then

...ruby code...
end



Comparison	Description

== Tests for equality. Returns true or false
.eql? Same as ==.
!= Tests for inequality. Returns true for inequality or false for equality
< Less than. Returns true if first operand is less than second operand. Otherwise returns false
> Greater than. Returns true if first operand is greater than second operand. Otherwise returns false.
>= Greater than or equal to. Returns true if first operand is greater than or equal to second operand. Otherwise returns false.
<= Less than or equal to. Returns true if first operand is less than or equal to second operand. Otherwise returns false.
<=> Combined comparison operator. Returns 0 if first operand equals second, 1 if first operand is greater than the second and -1 if first operand is less than the second.

&& Logical `AND'
|| Logical `OR'
! Logical negation

? : Ternary if-then-else


if customerName == "Fred"

print "Hello Fred!"
elsif customerName == "John"
print "Hello John!"
elsif customername == "Robert"
print "Hello Bob!"
else
print "You're not Fred! Where's Fred?"
end

unless i >= 10
puts "Student failed"
else
puts "Student passed"
end


Ternary is a bit of a shorthand version of if x then blah1 else blah2.
#Ternary

customerName == "Fred" ? "Hello Fred" : "Who are you?"


Case statements are a bit of shorthand for a series of if elsif statements.
car = "Patriot"


manufacturer = case car
when "Focus" then "Ford"
when "Navigator" then "Lincoln"
when "Camry" then "Toyota"
when "Civic" then "Honda"
when "Patriot" then "Jeep"
when "Jetta" then "VW"
when "Ceyene" then "Porsche"
when "Outback" then "Subaru"
when "520i" then "BMW"
when "Tundra" then "Nissan"
else "Unknown"
end


while and until run a block of code in a loop while (or until) an expression is true.
i = 0

while i < 5 do
puts i
i += 1
break if i == 2
end

i = 0
until i == 5
puts i
i += 1
end


for loops just run through a range of values.
for j in 1..5 do

for i in 1..5 do
print i, " "
break if i == 2
end
end



Well that was a whirlwind course on Ruby! Unless this is enough for you, I suggest you take a quick online tutorial on Ruby. Google "Ruby Tutorial" or go here: http://www.techotopia.com/index.php/Ruby_Essentials

Posts

Pages: 1
Trihan
"It's more like a big ball of wibbly wobbly...timey wimey...stuff."
3359
Currently working on the latest one, which is a breakdown of Game_Interpreter. That's one of the biggest ones I've done to date, and will basically explain how all the event commands work.
author=kentona
author=Chilly
Oh. OK.

Then hopefully somebody makes a version that's specific to that.
I believe in you. You can do it!

(here is trihan's work so far on it http://rpgmaker.net/users/Trihan/articles/ )

*** Oooh... Aaahh... ***

Very helpful. :) I've tinkered with a lot of people's scripts (ones in which there's express-written consent for us to do that, of course), though I've never written one of my own (for RPG Maker purposes, that is.)
author=Chilly
Oh. OK.

Then hopefully somebody makes a version that's specific to that.
I believe in you. You can do it!

(here is trihan's work so far on it http://rpgmaker.net/users/Trihan/articles/ )
Oh. OK.

Then hopefully somebody makes a version that's specific to that.
author=Chilly
author=andreasaspenberg
the ruby essentials guide is incompatible with the version of ruby that is in rpg maker vx ace.
Aw. I hope somebody makes an updated version.

Welp, this article is about Ruby in high level terms, and not specific to any RPG Maker scripting dialect.
author=andreasaspenberg
the ruby essentials guide is incompatible with the version of ruby that is in rpg maker vx ace.


Aw. I hope somebody makes an updated version.
Trihan
"It's more like a big ball of wibbly wobbly...timey wimey...stuff."
3359
Holy necropost, Batman!
the ruby essentials guide is incompatible with the version of ruby that is in rpg maker vx ace.
Thanks a bunch! This is a good quick and dirty way to dive into Ruby.
Trihan
"It's more like a big ball of wibbly wobbly...timey wimey...stuff."
3359
Just as a quick addition, arrays also have a method called .reject (or .reject!) with the syntax

array.reject { |value| block }

which will return an array of all elements from the original for which block returns false.
This... is going to take me awhile to get down, but it's much appreciated!
Pages: 1