Ruby (programming language)

from Wikipedia, the free encyclopedia
Ruby
logo
Official logo
Basic data
Paradigms : multi-paradigmatic, deeply integrated object orientation
Publishing year: 1995
Designer: Yukihiro Matsumoto
Developer: Yukihiro Matsumoto and others
Current  version 2.7.1   (March 31, 2020)
Typing : strong , dynamic (" duck typing ")
Important implementations : MRI / CRuby (YARV), JRuby , Rubinius (see below )
Influenced by: Smalltalk , Perl , Python , Lisp , CLU , Eiffel , Ada , Dylan , JavaScript
Affected: Crystal , D , Elixir , Groovy , Rust , Swift
Operating system : cross-platform
License : 2-clause BSD and own (see terms of use )
ruby-lang.org

Ruby (English for ruby ) is a high-level programming language that wasdesignedby the Japanese Yukihiro Matsumoto inthe mid-1990s.

Ruby is object-oriented , but supports several other programming paradigms (including procedural and functional programming and concurrency ), offers dynamic typing , reflection, and automatic garbage collection . A Ruby program is interpreted at runtime . In 2012, the Ruby specification was standardized as the international standard ISO / IEC 30170.

Origin and history

Ruby Creator, Yukihiro Matsumoto (2007)

Yukihiro "Matz" Matsumoto began working on his own language in 1993 and released the first version of Ruby, 0.95, on December 21, 1995. He chose the name, derived from the gemstone ruby , as an allusion to the Perl programming language . Matsumoto's goal in creating the new language was to synthesize elements of the programming languages Perl , Smalltalk , Eiffel , Ada and Lisp, which he valued , and to reconcile functional and imperative programming paradigms . In addition, the language should be more object-oriented than Python and at the same time more powerful than Perl . Flexibility, expressiveness and simplicity also played an important role.

In addition to the technical properties, Matsumoto's particularly important thing about Ruby was the emotional impact on users, co-developers and himself. Matsumoto's view on this is as follows:

“Of course, Ruby differs from Perl or Python in many ways; after all, that's Ruby's raison d'etre. Ruby's primary goal is "joy". As far as I know, there is no other language that focuses so much on joy. Ruby's ultimate goal is to please - language designers, users, language learners, everyone. However, joy is not everything. Ruby has many uses too. If you couldn't use it, it wouldn't be fun either. "

- Yukihiro Matsumoto : Foreword by the language creator in "Ruby プ ロ グ ラ ミ ン グ 入門" (translated)

In Japan , Ruby quickly gained notoriety after its release. In the west of the programming helped the book Programming Ruby (2000) (known as the Pickaxe book as a reference to the illustration on the cover) and the web framework Ruby on Rails (2004) breakthrough. In the years that followed, documentation and literature in English and German increased. The lingua franca of the core developers changed from Japanese to English. Today the language is maintained as an open source project and is the subject of various publications and courses. Releases with new functions usually take place annually at Christmas time.

A milestone in the development of Ruby was version 1.9 in 2007, which with many changes became quite incompatible with the previous versions. The interpreter was completely rewritten, which made Ruby programs much faster. Strings were given separate character encodings , variables in blocks became block-local, IPv6 support and some syntactic simplifications were introduced.

With Ruby 2.0 are keyword parameters (eg .: introduced 0.step(by: 5, to: 20)), the curtains (prepend) of modules and needs evaluation (lazy evaluation) introduced by iterators. In addition, the standard character encoding has been set to UTF-8 . Ruby 2.1 introduced refinements (a method to restrict class overrides locally). In Ruby 2.2, the existing garbage collector was replaced by an incremental one. With Ruby 2.3 it is possible to automatically create write-protected strings and a new operator &. (Safe-Navigation-Operator) for bypassing Nile checks has been introduced. In Ruby 2.4, the Fixnum and Bignum classes have been standardized. As of Ruby 2.5, exceptions can be caught in do-end blocks without separate sub-blocks. Every new Ruby version from 1.9 onwards also brought various speed optimizations with it. In addition, each version expanded the standard library with useful methods. Downward compatibility was always ensured, but not always 100 percent achieved.

features

Everything is an object

Ruby is a programming language that, while supporting many other programming paradigms, is fundamentally object-oriented. In concrete terms, this means that in Ruby, every value is an object and every function is a method (i.e. it is assigned to a class). There are no exceptions for primitive data types as in many other object-oriented programming languages. Classes are objects too. Objects store instance variables and have a class. Classes are objects that store methods and have an inheritance hierarchy. Instance variables can only be accessed using methods.

class TestKlasse
end
test_objekt = TestKlasse.new

puts 1.class            # => Integer
puts "text".class       # => String
puts test_objekt.class  # => TestKlasse
puts TestKlasse.class   # => Class
puts Class.class        # => Class

If "functions" are defined in Ruby, these are actually methods that are added to the Object object . In Ruby, all objects inherit implicitly from Object , which is why “functions” defined in this way are available in every object and are therefore ubiquitous. However, these functions are marked as private , which means that they cannot be called from outside on an object.

# Definiere „Funktion“
def meine_funktion
  puts "Hier bin ich"
end

# Kann in andern Objekten wie eine Funktion benutzt werden
class ABC
  def gib_meine_funktion_aus
    meine_funktion
  end
end
mein_abc = ABC.new
mein_abc.gib_meine_funktion_aus # => Hier bin ich
mein_abc.meine_funktion # => Fehlermeldung, private method `meine_funktion' called

Since objects are dynamic in Ruby, you can also program prototype-based with Ruby. This roughly means that objects can have their own methods (outside of those specified by the class) and can be copied and changed (since only classes can contain methods, a hidden new class is only created in the background for the one object).

auto1 = Object.new
def auto1.beschleunigen
  puts "brumm brumm brumm"
end

auto1.beschleunigen # => "brumm brumm brumm"

auto2 = auto1.clone
def auto2.bremsen
  puts "quietsch"
end

auto2.beschleunigen # => "brumm brumm brumm"
auto2.bremsen       # => "quietsch"

blocks

In most high-level programming languages, it is possible to pass functions in any form in addition as parameter logic, be it through first-class functions or first-class objects (whose methods then provide the logic). This is no different in Ruby, but Ruby has greatly optimized the syntax (and also in terms of computing power) the special case that exactly one function is passed. This special case will block called, meant as a block programming logic that has to use the function.

Blocks are passed to functions as separate parameters and follow as the last argument, delimited by curly brackets or the keywords do and end . In the following, the times method of object 10 is called and a block is transferred. Both calls are identical.

10.times {
  puts "Hallo Welt!"
}
10.times do
  puts "Hallo Welt!"
end

In addition, blocks can be given parameters and they also have a return value. The keyword yield is used within the called method to call the block passed . If yield parameters are specified, these are passed to the block, which can either declare them as local variables at the beginning or ignore them. Blocks (as well as methods) automatically return the last expression of the block as a return value ( but you can also jump back to other places using break and next ).

def methode_die_block_aufruft(übergebener_parameter)
  eigene_variable = "Hallo"
  rückgabe = yield eigene_variable, übergebener_parameter
  if rückgabe == "ok"
    puts "☺"
  end
end

# Aufruf
methode_die_block_aufruft("aus Ruby") do |p1,p2| # die Blockargumente werden innerhalb || in Block-lokale Variablen umgewandelt
  puts p1 + " " + p2 + "!"
  "ok"
end
# Zuerst wird im Block „Hallo aus Ruby!“ ausgegeben,
# dann in der Methode ☺, da der Rückgabewert „ok“ war

Blocks can also be converted into function objects. If a & is written in front of the last parameter in the parameter list of a method, Ruby converts the transferred block into a proc (a function object). Alternatively, procs can also be created manually using the key words proc , lambda and -> . These objects are called using the methods call , [] or . () . Since Ruby only uses round brackets for grouping, procs cannot be called (as is usual in other programming languages) proc_name().

def mache_block_zu_proc &block
  block # ist der Rückgabewert, da letzter Ausdruck
end
a = mache_block_zu_proc{|a,b| a + b}
b = proc {|a,b| a - b} # ein return innerhalb des Blocks verlässt die beinhaltende Methode, break nur den Block
c = lambda {|a,b| a * b} # wie proc, aber return innerhalb des lambdas verlässt nur diesen Block
d = -> (a,b) {a / b} # neue Schreibweise für lambda, runde Klammern sind optional
a.call(1,2) # => 3
b[1,2]      # => -1
c.(1,2)     # => 2

# Beispiel für funktionale Programmierung
e = d.curry.(8) # neues Proc das den (oder die) ersten Parameter (den Dividenden hier) als 8 setzt
e.(2)       # => 4
# mit & können Proc-Objekte (eigentlich jede Klasse die eine call Methode hat) wieder in Blöcke umgewandelt werden
[8,4,2,1].map(&e) # => [1, 2, 4, 8]

All blocks are closures , so they store e.g. B. the status of local variables if they are required permanently within the block.

Mixins

Ruby deliberately does not master multiple inheritance, but instead offers a concept called mixins (German: admixtures). Mixins are collections of methods that can be added to any class . A class can contain any number of mixins. Mixins are appended in the inheritance hierarchy between class and superclass in the order in which they were written. Alternatively, it is also possible to hang mixins in front of the actual class (useful for aspect-oriented programming, among other things ). To define mixins, Ruby uses modules, which are quasi classes (i.e. collections of methods) that cannot be instantiated and namespaces in one.

class Tier
  def sagt
    puts "#{self.class} sagt nichts" # "text#{logik}text" ist Rubys Textinterpolation
  end
end

module KannSchwimmen # Module, d.h. KannSchwimmen.new geht nicht
  def schwimmt
    puts "#{self.class} schwimmt" # self gibt die Instanz zurück,
  end                             #  jedes Objekt hat eine Methode .class die das Klassenobjekt zurück gibt
end

module KannNichtSchwimmen
  def schwimmt
    puts "#{self.class} geht unter"
  end
end

class Fisch < Tier # Vererbung wird durch den Kleiner-Als-Operator gekennzeichnet
  include KannSchwimmen # füge KannSchwimmen zwischen Fisch und Tier ein
end

class Vogel < Tier
  include KannNichtSchwimmen
  def sagt # übliches Vererben, überdecke sagt-Methode von Tier
    puts "#{self.class}: Piep"
  end
end

class Mensch < Tier
  include KannSchwimmen
  def sagt
    puts "#{self.class}: Ich kann mich besser ausdrücken"
  end
end

class NichtSchwimmer < Mensch
  prepend KannNichtSchwimmen # hänge KannNichtSchwimmen vor NichtSchwimmer ein,
end                          # dh, überdecke die schwimmt-Methode

fisch = Fisch.new
mensch = Mensch.new
vogel = Vogel.new
nicht_schwimmer = NichtSchwimmer.new

fisch.sagt                # => Fisch sagt nichts
vogel.sagt                # => Vogel: Piep
mensch.sagt               # => Mensch: Ich kann mich besser ausdrücken
nicht_schwimmer.sagt      # => NichtSchwimmer: Ich kann mich besser ausdrücken
puts
fisch.schwimmt            # => Fisch schwimmt
vogel.schwimmt            # => Vogel geht unter
mensch.schwimmt           # => Mensch schwimmt
nicht_schwimmer.schwimmt  # => NichtSchwimmer geht unter

Open classes

All classes are open in Ruby, which means that all methods can be exchanged later in the program. This also applies to all ruby-internal classes. To overwrite methods, all you have to do is create a new class with the same name as the class to be overwritten. Ruby then swaps or adds the newly defined methods. This technique is very powerful, but also enables hard-to-find errors, especially in larger projects. For this reason, it is also called slightly pejorative monkey patching . Refinements provide some remedy to the problems that arise , a possibility to restrict the overwriting locally. Vorzuhängen the previously presented method, the desired modules classes (prepend) , is usually the safe version (and the possibility also offers the covered method to directly call).

class Numeric # ruby-interne Klasse
  def inverse # neue Methode, berechne den Kehrwert
    1.0 / self
  end
end

5.inverse # => 0.2

Domain-specific language

Ruby is often used to create domain-specific languages . These are text modules that look less like program code and more like a markup language , but are actually normal Ruby code. This is made possible on the one hand by the flexible notation of Ruby, for example brackets after method calls or semicolons at the end of the line are optional. On the other hand, Ruby offers many possibilities for metaprogramming , which make it possible to make redundant expressions disappear and to change the program behind the scenes. As an example, the configuration of a test factory for FactoryBot :

FactoryBot.define do
  factory :user do
    first_name "Max"
    last_name  "Mustermann"
    admin false
  end
  factory :admin, class: User do
    first_name "Admin"
    last_name  "Root"
    admin true
  end
end

Powerful standard library

The core classes (string, integer, float, array, hash, range, regexp) have a wealth of methods that can be used immediately in any ruby ​​program. The frequent use of blocks in particular means that long programs can be reduced to a few lines with these methods, which is why Ruby is well suited for showing proof of concepts . The Enumerable module , which brings many functional programming concepts directly into the Ruby core, stands out. Enumerable can be integrated into any object that represents an iterable container and implements the each method, e.g. the classes Array, Hash and Range. For loops are therefore mostly unnecessary in Ruby. The methods reduce , count , sort_by , each_slice and map shown below are all methods from Enumerable and can therefore easily be added to classes you have created yourself.

# summiere die zahlen 1 bis 100 (ohne Summenformel), reduce entspricht fold aus der funktionalen Programmierung
(1..100).reduce{|counter,number| counter + number} # (1..100).sum geht auch
# Array aus den Zahlen von 0 bis 30 in 5er Schritten
(0..30).step(5).to_a
# Anzahl der Zeilen einer Datei die leer sind (ohne die Datei komplett in den Arbeitsspeicher zu laden)
IO.foreach("Dateiname").count{|line| line =~ /^\s*$/}
# Sortiere Array nach Länge der Nachnamen
["Max Mustermann", "John Doe", "Tarou Yamada"].sort_by{|name| name.split.last.length}
# Schreibe jedes dritte Wort im Satz in Großbuchstaben
"Franz jagt im komplett verwahrlosten Taxi quer durch Bayern.".split.each_slice(3).map{|drei_wörter| drei_wörter.last.upcase!; drei_wörter}.flatten.join(" ")

In addition to the integrated modules, Ruby is delivered with many modules as standard. E.g. Support for JSON , YAML , HTTP , benchmarks, prime numbers, secure random numbers, OpenSSL and logging is immediately available.

Metaprogramming

Ruby offers extensive possibilities for metaprogramming . So it is z. B. possible to generate methods, exchange instance variables, change the inheritance hierarchy or edit constants. Changing the syntax or adding additional operators is not possible. A method for automatically generating setters and getters is listed here as an example ( already included in the standard under the names attr_reader , attr_writer , attr_accessor ).

class Object # Monkey-Patching aller Klassen
  def self.getter *args # self ist hier Object, es wird eine Klassenmethode erzeugt
    args.each do |arg| # es wird durch alle Parameter iteriert
      define_method arg do # define_method(arg){block} erzeugt eine neue Methode des Names arg mit dem Inhalt block
        instance_variable_get("@#{arg}".to_sym) # instance_variable get gibt den Wert der Instanzvariablen des übergeben Namens zurück
      end                                       # \- "@#{arg}" hängt ein @ vor den Inhalt von arg, to_sym wandelt den String um in ein Symbol
    end
  end
  def self.setter *args # *args packt alle Parameter in ein Array namens args
    args.each do |arg|
      define_method :"#{arg}=" do |new_value|              # define_method übergibt dem Block die übergeben Parameter
        instance_variable_set("@#{arg}".to_sym, new_value) # \- setter-methoden enden mit einem =
      end
    end
  end
end

class PaarMit2
  def initialize links # Konstruktor
    @links = links # Instanzvariblen werden bei Erwähnung in einer beliebigen Methode automatisch erzeugt
    @rechts = 2
  end
  getter :links, :rechts
  setter :links
end

paar = PaarMit2.new(4) # new ruft immer den Konstruktor auf
paar.links       # => 4
paar.rechts      # => 2
paar.links = 9   # => 9
paar.links       # => 9
paar.rechts = 8  # => Fehler: NoMethodError (undefined method `rechts=')

These techniques are also good for debugging applications or analyzing poorly documented applications or libraries. E.g. each object responds when the method is called methodswith a list of all its methods, and instance_variablesreturns a list of all instance variables.

Integration in Unix

Like Perl , Ruby can be integrated directly into the Unix shell's pipeline . This is made possible by the command line parameters of the Ruby interpreter, which allow the program logic and usual program behavior to be defined (usually the same operation to be carried out on each line). Ruby extends the standard Unix tools with advanced methods for text analysis and word processing.

Ruby also offers the option of conveniently starting processes within a program, controlling their input and reading out output and return values. Code within `` is passed directly to the Unix shell. E.g. the command saves os_string = `uname -a`the operating system name directly in a Ruby variable. The return value of the last program call is automatically $?saved in the global variable, like in the shell . Signal handling, sockets and threads are also supported directly by the language core without additional libraries. To speed up processing there is a module in Ruby called FileUtils , which maps much of the functionality of many Unix file management programs ( rm , cp , chmod ) directly in Ruby.

Syntax and basics

Naming convention

Ruby follows the usual convention for method and variable names, a name must begin with a lowercase letter or underscore, then any letters (after Unicode ), digits and underscores can follow. Methods can also end with an exclamation point or question mark. According to the usual convention, the former serves as an indication that this method is a sharper version of the same method without an exclamation mark (changes the state of the object, throws errors, ...), the latter means that the function returns a Boolean (true or false). If a variable name begins with a capital letter, it is a constant. Variables can also begin with a special character that describes the scope.

Variable identifier

Ruby distinguishes between five areas of validity:

  • Usually a variable is locally valid within the surrounding block or method.
  • A @prior variables declared instance variable, they are then permanently the instance assigned and are visible only in this. Instance variables can only be accessed from outside using methods. Access to non-existing instance variables throw an error, but give nil return
  • A preceding @@makes variables class variables that belong to the surrounding class.
  • With $variables become global and are therefore visible in the entire program.
  • The validity range for constants depends on the local nesting depth and can be ::specified with

Method calls and expressions

In Ruby, method calls are not necessarily marked with the following brackets. gets.chompis therefore equivalent to gets().chomp(). If methods require parameters, these must be put in brackets if another operation is to be performed on the result. "a,b,c".split ","is ok, "a,b,c".split(",").join(" ")but requires the first pair of brackets. Since brackets are also used for grouping, a space should never be placed between the method name and bracket when calling the method ( [1,2].join␣("|") * 2 != [1,2].join("|") * 2 => [1,2].join(("|") * 2) != ([1,2].join("|")) * 2 => "1||2" != "1|21|2").

Each statement forms an expression that can be assigned to a variable. Individual statements are separated by line breaks or semicolons. The last expression within a method automatically forms its return value. However, it is also possible to jump back early with the keyword return .

Data types

The elementary data types have more convenient constructors than the usual Klasse.new

  • String: "Text", 'Text'or %{Text} text
  • Integer: 3(ten system), 0775or 0o775(octal system), 0xFF(hexadecimal system) 0b1001(binary system) integer (unlimited size)
  • Float: 3.0 floating point number (limited precision)
  • Rational: 1/2r Rational number
  • Complex: 1 + 1i complex number
  • Array: [1,2,3] Collection, can contain any number of different data types
  • Hash: { 1 => "eins", 2 => "zwei" } Assignment, assigns exactly one value to each value in front of the arrows (key)
  • Regexp: /\A(eins|zwei)\z/or %r{\A(eins|zwei)\z} regular expression
  • Range: 1..3or 1...4(excluding the right element) interval
  • Symbol: :zeichen Symbol, see below

Dynamic strings

By default, character strings can be changed in Ruby; H. a string object can change its value at runtime. text = "Felar"; text[2..3] = "hle"; puts textchanges the value of textdirect (and returns errors ). Many string methods are available both in a modifying variant and in a variant that creates a new string object.

a = "ABC"
b = a.downcase
puts a, b # => ABC abc
a.downcase!
puts a, b # => abc abc

Like any Ruby object, strings can be freezefrozen by calling the method (e.g. "ABC".freeze) and are then unchangeable.

Symbols

This somewhat unusual and also controversial data type is a kind of mixture of integer and string. It serves primarily as a memory aid for keys of hashes, since dynamic strings are impractical here and integers require little memory. Symbols do not have the text manipulation methods of String, but can be converted to strings at any time. If symbols in hashes are used as keys, a simplified notation can be used. Instead { :a => 1, :b => 2 }you can also { a: 1, b: 2 }write. Symbols are also frequently used internally in Ruby, so methods can also be called with their symbol name: 1 < 4can also be 1.send(:<, 4)written as. Simple blocks that only call one method of the transferred object can be written in a simplified manner using symbols, whereby the symbol denotes the method to be called. [1,2,3].map{|i| i.to_s}can also be [1,2,3].map(&:to_s)written as (& converts the symbol to a block).

Truth values

In Ruby, there are three different truth values true, falseand nil. Nil stands for a missing result and, like false, is evaluated as false . True and all other objects are evaluated as true . puts "Ja!" if 0so evaluates to true , “Yes!” is output.

Error handling

In most programming languages, the part of the program to be checked for errors must be explicitly marked (mostly using the keywords try and catch ); in Ruby, for the most common cases, the program part encompasses the entire method or the entire block, no extra area has to be marked. If a delimitation should be necessary, the area can be marked with begin and end .

def gib_summe_aus arg1, arg2
  # Methodenlogik
  unless arg1.is_a?(Numeric) && arg2.is_a?(Numeric)
    raise ArgumentError.new("Bitte nur Zahlen eingeben") # raise wirft Fehler
  end
  puts arg1 + arg2
rescue ArgumentError => e # Fange ArgumentError ab
  puts "Es ist ein Fehler bei der Parameterübergabe aufgetreten"
rescue => e # Fange alle weiteren Fehler ab
  puts e.message
ensure # wird auf jeden Fall ausgeführt
  puts 'Methodenende'
end

Alternative conditions / loops

Conditions and loops provide both postfix notation and their own keyword for the inverse (inspired by Perl ).

a = 5
if a < 10;  puts a; end
puts a if a < 10 # Suffixform
unless a >= 10; puts a; end # Invers
puts a unless a >= 10 # Invers + Suffixform

while a < 10;  puts a;  a += 1; end
(puts a; a+=1) while a < 20 # Suffixform
until a >= 30;  puts a;  a += 1; end # Invers
(puts a; a +=1) until a >= 40 # Invers + Suffixform

Regular expressions

In Ruby, regular expressions are contained directly in the language core. Ruby uses its own regex engine called Onigmo , the syntax and functionality of which is for the most part compatible with PCRE . In addition, it is possible to interpolate Ruby variables directly into regular expressions and to use any program logic through blocks for searching and replacing. E.g. The following command adds all numbers in a text by one:puts "test, 1, 2, 3".gsub(/(\d+)/){|zahl| zahl.to_i + 1} # => test, 2, 3, 4

Constants

In Ruby, constants are all variables that start with a capital letter. All classes and modules are therefore constants. The special thing about constants in Ruby is their nesting. Constants within constants can be ::called using and are not subject to any access rights (such as methods or instance variables). That is why modules can be used as namespaces, all variables remain hidden in them, all constants (such as classes) can be qualified (for example MeinModul::MeineKlasse.new) accessed via the module name .

Components

Interactive Ruby Shell

Interactive Ruby ( irb ) is a Read-Eval-Print Loop (REPL) with which the user can interactively program Ruby. Irb is supplied with the Ruby interpreter and can be used for analysis and testing:

irb(main):001:0> (5 + 7) * 2
=> 24
irb(main):002:0> ((5 + 7) * 2).to_s.reverse
=> "42"
irb(main):003:0> "Ein Beispielstring".size
=> 18

As an alternative to Irb there is Pry , a REPL, which brings far more profound possibilities for introspection and debugging .

RDoc and ri

RDoc is a software documentation tool that automatically creates HTML documentation files from Ruby and C source texts . A database is also set up that can be searched using the ri tool. RDoc and ri are part of the standard distribution and are supplied together with the interpreter.

Rake

Rake is Ruby Make and is an alternative to make from C . Since there is no compilation phase in Ruby, rakefiles are used to automate repetitive tasks, e.g. generating documentation, uploading files or packing projects. Like Make, Rake can resolve dependencies, if task A has to be completed first for task B, then Rake automatically performs task A. Rake is a domain-specific language ; H. it can be read as comfortably as a markup language, but offers the full capabilities of Ruby.

Package management

Ruby libraries are usually packaged as Gems (RubyGems) and published on rubygems.org, the central gem registry. RubyGems automatically resolves the dependencies specified in the package recursively during installation or updates and even offers the possibility of providing packages in different versions at the same time. Rubygems has been part of the Ruby standard library since Ruby 1.9. Today it is mostly used in conjunction with Bundler, a program that takes snapshots of a collection of gems and can restore this arrangement on other machines (or other project folders).

Implementations

Reference implementation

The reference implementation of Ruby was designed by Yukihiro "Matz" Matsumoto as an interpreter in C. This is usually referred to as MRI (Matz's Ruby Interpreter) or CRuby and is currently the most common. The core is YARV (Yet Another Ruby VM) , a virtual machine . Instead of executing a Ruby program directly, it is first translated into bytecode and then interpreted by YARV, which results in a speed advantage. This version also contains a powerful regexp engine called Oniguruma and supports multibyte character sets such as UTF-8 .

The official interpreter runs on the following operating systems:

Alternative implementations

There are numerous alternative Ruby implementations of varying scope and goals:

  • JRuby , a new implementation of the Ruby interpreter in Java with the aim of seamlessly integrating Ruby into the Java platform . JRuby is almost completely compatible with Ruby 2.3. JRuby is also compatible with some Ruby extensions from Rubinius (Foreign Function Interface, Multi-VM-API), but not with C extensions from CRuby.
  • Rubinius , animplementation inspiredby Smalltalk-80 . Apart from the virtual machine, Rubinius is written entirely in Ruby. Rubinius is almost completely compatible with Ruby 2.3. Rubinius uses the Low Level Virtual Machine (LLVM) and is compatible with C extensions of the reference implementation.
  • Mruby is another Ruby implementation made by Ruby creator Yukihiro Matsumoto. Mruby is aversion of Ruby tailoredto embedded systems , which is characterized by low memory requirements and high modularization. Mruby does not provide the full functionality of CRuby. Mruby can translate the source code into bytecode, which can then beinterpretedwithout a compilation steporembeddedin C programs.
  • Opal is a Ruby to JavaScript compiler. It is an implementation of the Ruby Corelib and Stdlib, as well as the associated gems. With Opal, client-side web applications can be implemented in Ruby. There are some restrictions that are due to the implementation according to JavaScript.
  • TruffleRuby is a Ruby implementation that runs on the GraalVM. The aim of the implementation is to make the advantages of GraalVM usable by means of Ruby. These are speed (start and runtime), parallelization and the controlled execution of C extensions. TruffleRuby is largely developed by Oracle .

Historic Ruby implementations:

  • IronRuby is an implementation thatintegratesRuby in the .NET Framework andis implementedin C # .
    The project has been inactive since March 13, 2011 and is no longer being developed.
  • Cardinal , an interpreter for the Parrot virtual machine. The project has been inactive since June 2013.
  • MagLev is an implementation by Gemstone for their proprietary Smalltalk VM. The project has been inactive since 2015.
  • MacRuby is an implementation in Objective-C from Apple that uses YARV up to version 0.4, like Ruby 1.9, but from version 0.5, like Rubinius ,usesthe LLVM . The further development was discontinued on January 5th, 2015.
  • Ruby Enterprise Edition is a modified version of the reference implementation that essentiallyre-implementedthe garbage collector . REE is only compatible with Ruby 1.8, the latest version is from 2012.

The compatibility with the reference implementation is checked by the RubySpec project. It represents both a test suite and a specification for Ruby. RubySpec was originally part of Rubinius, but was outsourced and then promoted by a large number of other developers. It is used in many Ruby implementations.

With the help of the Ruby Version Manager or Rbenv it is possible to operate several Ruby implementations and Gem versions in parallel.

An important characteristic of the implementations is whether they are able to run Ruby on Rails . Currently only JRuby and Rubinius can do this in addition to the reference implementation.

Spread and use

Ruby is freely available for all common desktop operating systems; in most Linux distributions it is included in the package sources supplied, and even preinstalled under macOS.

Ruby is widely used as a web server scripting language. The most common framework here is Ruby on Rails , although there are numerous alternatives of different sizes (e.g. Sinatra and Hanami). The list of big rail projects is long, the best known are possibly commercial websites like GitHub and Airbnb or community projects like Diaspora , Redmine and Discourse . Web technologies written in Ruby, such as Sass and Haml, are also used outside of the Ruby ecosystem.
Ruby is widely used as a scripting language for managing and automating server tasks, starting as a replacement for more complex Bash scripts as well as for larger applications, e.g. Puppet (server configuration over the network), Metasploit ( penetration tests) , YaST ( OpenSUSE server administration) and Vagrant (virtual machine management).
Ruby is also often used as a domain-specific language because of its flexible syntax. With mruby there is also a Ruby variant that specializes in embedded systems . Occasionally Ruby is also used as a script language in games, for example in RPG Maker .

criticism

Criticism of the language was made for various reasons:

  • Since variables do not need to be declared before use, typing errors can lead to unexpected runtime errors.
  • Ruby is not always backwards compatible .
  • Metaprogramming and monkeypatching allow a piece of code to change all classes and objects of the process in which it is executed.

Critics also criticize several aspects of the reference implementation:

Others

Terms of Use

Ruby is free software . Therefore it is free to use and available in the source code . This gives you the opportunity to adapt the language to your own needs or to integrate it into your own programs.

The Ruby interpreter and the standard library can be used under the conditions of the 2-clause BSD license . You can also use Ruby under your own free license. The Ruby license is GPL-compatible and is accepted as "free" by the Free Software Foundation .

Older versions of Ruby (1.9.2 and earlier) used the GPL V2 instead of the BSD license . The reasons given for the change were incompatibilities between the old licensing and GPL V3.

RubyForge

RubyForge was a collaborative File Hosting - Services for written in Ruby software projects. It was started by Ruby Central in 2003 to provide the Ruby community with a home for their open source projects.

On November 29, 2009 over 9,300 projects and more than 94,683 users were carried out there, and the service was finally discontinued on May 15, 2014.

literature

For programming beginners

Entry level for programmers

Specialization for programmers

  • David A. Black: The Well-Grounded Rubyist . 2nd Edition. Manning, Shelter Island 2014, ISBN 978-1-61729-169-2 (English, errata , source code ).
  • Hal Fulton, André Arko: The Ruby Way. Solutions and Techniques in Ruby Programming . 3. Edition. Addison-Wesley, Upper Saddle River, et al. a. 2015, ISBN 978-0-321-71463-3 (English, excerpt [PDF]).

Overall representations

  • David Flanagan, Yukihiro Matsumoto: The Ruby Programming Language . O'Reilly Media, 2008, ISBN 978-3-89721-874-1

For advanced

  • Lucas Carlson, Leonard Richardson: Ruby Cookbook . O'Reilly Media, 2nd edition 2015, ISBN 1-4493-7371-2 (English)
  • Pat Shaughnessy: Ruby Under a Microscope . No Starch Press, 1st edition 2013, ISBN 1-59327-527-7 (English)
  • Russ Olsen: Eloquent Ruby . Addison-Wesley Professional, 2011, ISBN 978-0-321-58410-6 (English)
  • Russ Olsen: Design Patterns in Ruby . Addison-Wesley Professional, 2007, ISBN 978-0-321-49045-2 (English)

Norms and standards

  • ISO / IEC 30170 (English; standardized Ruby on over 317 pages). First version April 2012.

Web links

Commons : Ruby  - collection of images, videos and audio files
Wikibooks: Ruby Programming  - Learning and Teaching Materials

Individual evidence

  1. www.ruby-lang.org .
  2. Release 2.7.1 . March 31, 2020 (accessed April 1, 2020).
  3. ^ D Programming Language 1.0, Intro. Digital Mars
  4. iso.org
  5. RubyConf: History of Ruby
  6. An interview with the creator of Ruby
  7. About Ruby. Retrieved October 4, 2018 .
  8. ^ RVM: Ruby Version Manager - RVM Ruby Version Manager - Documentation. Retrieved October 4, 2018 .
  9. rbenv / rbenv. Accessed October 4, 2018 .
  10. JRuby Wiki. Retrieved February 23, 2017 .
  11. Evan Phoenix: Rails on Rubinius. May 17, 2008, archived from the original on March 22, 2016 ; accessed on February 23, 2017 (English).
  12. infoq.com
  13. Avdi Grimm: Monkeypatching is Destroying Ruby. February 23, 2008, accessed February 23, 2017 .
  14. infoq.com
  15. igvita.com
  16. Ruby's license terms. Retrieved February 23, 2017 .
  17. List of GPL-compatible licenses. Retrieved February 23, 2017 .
  18. Mailing list discussion on license change. Archived from the original on June 11, 2015 ; Retrieved July 8, 2012 .
  19. Decision to change licenses at the Ruby Developers Meeting 2010. Accessed on February 23, 2017 .
  20. RubyForge ( Memento from May 31, 2014 in the Internet Archive )
  21. Twitter message from Evan Phoenix. Retrieved March 28, 2014 .