Ruby (programmeertaal)
Robijn | |
---|---|
![]() Officieel logo | |
Basis data | |
paradigma's : | multiparadigmatische, diep geïntegreerde objectoriëntatie |
Jaar van uitgave: | 1995[1] |
Ontwerper: | Yukihiro Matsumoto |
Ontwikkelaar: | Yukihiro Matsumoto en anderen |
Huidige versie | 3.0.1[2] (5 april 2021) |
Typen : | sterk , dynamisch (" eendentypering ") |
Belangrijke implementaties : | MRI / CRRuby (YARV), JRuby , Rubinius (zie hieronder ) |
Beïnvloed door: | Smalltalk , Perl , Python , Lisp , CLU , Eiffel , Ada , Dylan , JavaScript |
Aangedaan: | Kristal , D , [3] Elixer , Groovy , Roest , Swift |
Besturingssysteem : | platformonafhankelijk |
Licentie : | 2-clausule BSD en eigen (zie gebruiksvoorwaarden ) |
ruby-lang.org |
Ruby (Engels voor ruby ) is een programmeertaal op hoog niveau die halverwege de jaren negentig werd ontworpen door de Japanner Yukihiro Matsumoto .
Ruby is objectgeoriënteerd , maar ondersteunt verschillende andere programmeerparadigma's (waaronder procedureel en functioneel programmeren en gelijktijdigheid ), biedt dynamisch typen , reflectie en automatische garbagecollection . Een Ruby-programma wordt tijdens runtime geïnterpreteerd . In 2012 is de Ruby-specificatie gestandaardiseerd als de internationale norm ISO/IEC 30170. [4]
Oorsprong en geschiedenis
Yukihiro "Matz" Matsumoto begon in 1993 aan zijn eigen taal te werken en bracht op 21 december 1995 de eerste versie van Ruby uit, 0.95. [5] Hij koos de naam afgeleid van de edelsteen robijn , als een zinspeling op de Perl programmeertaal taal . [6] Matsumoto's doel bij het creëren van de nieuwe taal was om elementen van de programmeertalen Perl , Smalltalk , Eiffel , Ada en Lisp te synthetiseren , die hij op prijs stelde, en om functionele en imperatieve programmeerparadigma's met elkaar te verzoenen. Bovendien moet de taal meer objectgeoriënteerd zijn dan Python en tegelijkertijd krachtiger dan Perl . Ook flexibiliteit, zeggingskracht en eenvoud speelden een belangrijke rol. [7]
Naast de technische eigenschappen was Matsumoto's bijzonder belangrijke aan Ruby de emotionele impact op gebruikers, mede-ontwikkelaars en hemzelf.Matsumoto's visie hierop is als volgt:
“Natuurlijk verschilt Ruby in veel opzichten van Perl of Python, dat is tenslotte de bestaansreden van Ruby. Primaire doel Ruby's is "vreugde". Voor zover ik weet, is er geen andere taal die zoveel op vreugde is gericht. Het uiteindelijke doel van Ruby is om te behagen - taalontwerpers, gebruikers, taalleerders, iedereen. Vreugde is echter niet alles. Ruby heeft ook veel toepassingen. Als je het niet zou kunnen gebruiken, zou het ook niet leuk zijn."
In Japan verwierf Ruby al snel bekendheid na de release. In het westen van de programmering hielpen het boek Programming Ruby (2000) (bekend als het Pickaxe-boek als verwijzing naar de illustratie op de omslag) en het webframework Ruby on Rails (2004) doorbreken. In de daaropvolgende jaren nam de documentatie en literatuur in het Engels en Duits toe. De lingua franca van de kernontwikkelaars veranderde van Japans in Engels. Tegenwoordig wordt de taal in stand gehouden als een open source- project en is het onderwerp van verschillende publicaties en cursussen. Releases met nieuwe functies vinden meestal jaarlijks plaats in de kersttijd.
Een mijlpaal in de ontwikkeling van Ruby was versie 1.9 in 2007, die met veel veranderingen behoorlijk incompatibel werd met de vorige versies. De semantiek van sommige constructies is in deze versie gewijzigd. [8] De interpreter werd volledig herschreven, waardoor Ruby-programma's veel sneller werden. Strings kregen aparte karaktercoderingen , variabelen in blokken werden block-local, IPv6- ondersteuning en enkele syntactische vereenvoudigingen werden geïntroduceerd.
Met Ruby 2.0 zijn trefwoordparameters (bijv.: geïntroduceerd 0.step(by: 5, to: 20)
), (vooraan) de gordijnen van modules en vraaganalyse geïntroduceerd (luie-evaluatie) van iterators. Daarnaast is de standaard karaktercodering ingesteld op UTF-8 . Ruby 2.1 introduceerde verfijningen (een methode om klasseoverschrijvingen lokaal te beperken). In Ruby 2.2 werd de bestaande garbage collector vervangen door een incrementele. Met Ruby 2.3 is het mogelijk om automatisch alle tekenreeksen te maken die tegen schrijven zijn beveiligd en een nieuwe operator &.
(Safe-Navigation-Operator) om Nijlcontroles te omzeilen is geïntroduceerd. In Ruby 2.4 zijn de klassen Fixnum en Bignum gestandaardiseerd. Vanaf Ruby 2.5 kunnen uitzonderingen worden opgevangen in do-end blokken zonder aparte subblokken. Ruby 2.6 leverde de eerste code voor een optionele JIT-compiler en voegde Bundler (zie hieronder ) toe aan de standaarddistributie. Ruby 2.7 voegde uitgebreide patroonafstemming en wat syntactisch reliëf toe aan de taalkern. Elke nieuwe Ruby-versie vanaf 1.9 bracht ook verschillende snelheidsoptimalisaties met zich mee. Bovendien breidde elke versie de standaardbibliotheek uit met handige methoden. Neerwaartse compatibiliteit was altijd verzekerd, maar niet altijd 100 procent.
Ruby 3.0, uitgebracht op 25 december 2020, is de eerste versie die voldoet aan de vereisten genaamd "Ruby 3x3": drie keer hogere uitvoeringssnelheid dan Ruby 2.0 (via JIT-compiler), gelijktijdigheid zonder GIL (maar nog steeds experimenteel) en statische typeanalyse (optioneel). De daadwerkelijke update 3.0 is echter geen grotere sprong dan de vorige jaarlijkse releases en is neerwaarts compatibel met Ruby 2.x.
Kenmerken
Alles is een object
Ruby is een programmeertaal die, hoewel hij vele andere programmeerparadigma's ondersteunt, fundamenteel objectgeoriënteerd is. Concreet betekent dit dat in Ruby zonder uitzondering elke waarde een object is en elke functie een methode (dwz wordt toegewezen aan een klasse). Er zijn geen uitzonderingen voor primitieve gegevenstypen zoals in veel andere objectgeoriënteerde programmeertalen. Klassen zijn ook objecten. Objecten slaan instantievariabelen op en hebben een klasse. Klassen zijn objecten die methoden opslaan en een overervingshiërarchie hebben. Instantievariabelen zijn alleen toegankelijk met methoden.
klasse test klasse
einde
test_object = testklasse . nieuwe
zet 1 . klasse # => geheel getal
zet "tekst" . klasse # => tekenreeks
zet test_object . class # => TestClass
zet TestClass . klasse # => Klasse
klasse zet . klasse # => Klasse
Als "functies" worden gedefinieerd in Ruby, dit zijn eigenlijk methoden die worden toegevoegd aan het object object. In Ruby erven alle objecten impliciet van Object , daarom zijn op deze manier gedefinieerde "functies" beschikbaar in elk object en zijn daarom alomtegenwoordig. Deze functies zijn echter gemarkeerd als privé , wat betekent dat ze niet van buitenaf op een object kunnen worden aangeroepen.
# Definieer "functie"
def mijn_functie
zet "Hier ben ik"
einde
# Kan in andere objecten worden gebruikt, zoals een functie
klasse ABC
def output_my_function_
mijn_functie
einde
einde
mijn_abc = ABC . nieuwe
mijn_abc . give_my_function_out # => Hier ben ik
mijn_abc . my_function # => foutmelding, private methode `my_function 'aangeroepen'
Omdat objecten dynamisch zijn in Ruby, kunt u met Ruby ook prototype-gebaseerd programmeren. Dit betekent ruwweg dat objecten hun eigen methoden kunnen hebben (buiten die gespecificeerd door de klasse) en kunnen worden gekopieerd en gewijzigd (aangezien alleen klassen methoden kunnen bevatten, wordt een nieuwe verborgen klasse alleen op de achtergrond gemaakt voor dat ene object).
auto1 = Object . nieuwe
def auto1 . versnellen
zet "hum hum hum"
einde
auto1 . versnellen # => "hum brom brom"
auto2 = auto1 . kloon
def auto2 . rem
zet "piepen"
einde
auto2 . versnellen # => "hum brom brom"
auto2 . rem # => "piepen"
blokken
In de meeste programmeertalen op hoog niveau is het mogelijk om functies in elke vorm als parameterlogica door te geven, of het nu gaat om eersteklas functies of eersteklas objecten (waarvan de methoden dan de logica leveren). Bij Ruby is dat niet anders, maar Ruby heeft het speciale geval waar precies één functie wordt doorgegeven, syntactisch (en ook qua rekenkracht) sterk geoptimaliseerd. Dit speciale geval wordt blok genoemd, bedoeld als een blokprogrammeerlogica die de functie moet gebruiken.
Blokken worden als afzonderlijke parameters aan functies doorgegeven en volgen als laatste argument, gescheiden door accolades of de trefwoorden do en end . Hierna wordt de times- methode van object 10 aangeroepen en een blok overgedragen. Beide oproepen zijn identiek.
10 . keer {
zet "Hallo wereld!"
}
10 . keer doen
zet "Hallo wereld!"
einde
Daarnaast kunnen blokken parameters worden gegeven en hebben ze ook een retourwaarde. De trefwoordopbrengst wordt binnen de aangeroepen methode gebruikt om het doorgegeven blok aan te roepen. Als opbrengstparameters zijn opgegeven, worden deze doorgegeven aan het blok, dat ze aan het begin als lokale variabelen kan declareren of ze kan negeren. Blokken (evenals methoden) retourneren automatisch de laatste uitdrukking van het blok als een retourwaarde (maar je kunt ook terugspringen naar andere plaatsen met break en next ).
def methode_die_block_aufruft (g bergebener_parameter)
own_variable = "Hallo"
retourneerbaar = opbrengst eigene_variabele, ü bergebener_parameter
if return == "ok"
zet "☺"
einde
einde
# Telefoongesprek
method_the_block_calls ( "van Ruby" ) do | p1 , p2 | # de blokargumenten zijn binnen || geconverteerd naar blok-lokale variabelen
zet p1 + "" + p2 + "!"
"OK"
einde
# Eerst, "Hallo van Ruby!" Wordt uitgevoerd in het blok,
# dan in methode ☺, omdat de geretourneerde waarde "ok" was
Blokken kunnen ook worden omgezet in functieobjecten. Als een & voor de laatste parameter in de parameterlijst van een methode wordt geschreven, converteert Ruby het overgedragen blok naar een proc (een functieobject). Als alternatief kunnen procs ook handmatig worden aangemaakt met de trefwoorden proc , lambda en -> . Deze objecten worden aangeroepen met behulp van de methoden call , [] of .() . Omdat Ruby alleen ronde haakjes gebruikt voor groepering, kunnen procs niet (zoals gebruikelijk is in andere programmeertalen) worden aangeroepen met proc_name()
.
def make_block_to_proc & block
blok # is de geretourneerde waarde, als de laatste uitdrukking
einde
a = do_block_zu_proc { | een , b | een + b }
b = proc { | een , b | a - b } # a return binnen het blok verlaat de methode met daarin, breek alleen het blok
c = lambda { | een , b | a * b } # like proc, maar return binnen de lambda verlaat alleen dit blok
d = -> ( a , b ) { a / b } # nieuwe notatie voor lambda, ronde haakjes zijn optioneel
een . bel ( 1 , 2 ) # => 3
b [ 1 , 2 ] # => -1
c . ( 1 , 2 ) # => 2
# Voorbeeld van functioneel programmeren
e = d . kerrie . ( 8 ) # nieuwe procedure die de eerste parameter (of parameters) (de dividenden hier) instelt als 8
e . ( 2 ) # => 4
# met & je kunt Proc-objecten (eigenlijk elke klasse die een aanroepmethode heeft) terug naar blokken converteren
[ 8 , 4 , 2 , 1 ]. kaart ( & e ) # => [1, 2, 4, 8]
Alle blokken zijn sluitingen , zodat ze b.v. B. de status van lokale variabelen als ze permanent nodig zijn binnen het blok.
Mixins
Ruby beheerst bewust geen meervoudige overerving, maar biedt in plaats daarvan een concept genaamd mixins (Duits: hulpstoffen). Mixins zijn verzamelingen methoden die aan elke klasse kunnen worden toegevoegd . Een klasse kan een willekeurig aantal mixins bevatten. Mixins worden toegevoegd in de overervingshiërarchie tussen klasse en superklasse in de volgorde waarin ze zijn geschreven. Als alternatief is het ook mogelijk om mixins voor de eigenlijke klas te hangen (handig voor onder andere aspectgericht programmeren ). Om mixins te definiëren, worden in Ruby modules gebruikt, dit zijn quasi-klassen (dwz verzamelingen van methoden) die niet kunnen worden geïnstantieerd en naamruimten in één.
klasse dier
zeker zegt
puts " # { self . class } zegt niets" # "text # {logic} text" is Ruby's tekstinterpolatie
einde
einde
module KannSchwimmen # Module, dwz KannSchwimmen.new werkt niet
zeker zwemt
puts " # { self . class } floats" # self retourneert de instantie
end # elk object heeft een .class-methode die het class-object retourneert
einde
module kan niet zwemmen
zeker zwemt
zet " # { self . class } goes under"
einde
einde
class fish < tier # overerving wordt aangegeven door de operator kleiner dan
inclusief CanSwimming # voeg CanSwimming toe tussen vis en dier
einde
klasse vogel < dier
omvatten Kan niet zwemmen
def zegt # gebruikelijke overerving, dekking zegt methode van dier
zet " # { self . class } : piep"
einde
einde
klasse mens < dier
inclusief CanSwim
zeker zegt
zet " # { self . class } : ik kan mezelf beter uitdrukken"
einde
einde
klasse niet-zwemmer < mens
prepend Kan niet zwemmen # append Kan niet zwemmen op een niet-zwemmers,
end # dat wil zeggen, bedek de floats-methode
vis = vis . nieuwe
mens = mens . nieuwe
vogel = vogel . nieuwe
nicht_schwimmer = NietSwimmer . nieuwe
vissen . zegt # => vis zegt niets
vogel . zegt # => vogel: piep
mens . zegt # => mens: ik kan mezelf beter uitdrukken
niet_zwemmer . zegt # => geen zwemmers: ik kan mezelf beter uitdrukken
zet'
vissen . zwemt # => vis zwemt
vogel . zwemt # => vogel gaat onder
mens . zwemt # => man zwemt
niet_zwemmer . zwemt # => niet-zwemmer gaat onder
Open lessen
Alle klassen zijn open in Ruby, wat betekent dat alle methoden later in het programma kunnen worden uitgewisseld. Dit geldt ook voor alle ruby-interne klassen. Om methoden te overschrijven, hoeft u alleen maar een nieuwe klasse te maken met dezelfde naam als de klasse die moet worden overschreven. Ruby verwisselt of voegt dan de nieuw gedefinieerde methoden toe. Deze techniek is zeer krachtig, maar maakt ook moeilijk te vinden fouten mogelijk, vooral bij grotere projecten. Om deze reden wordt het ook wel licht pejoratieve apenpatching genoemd . Verfijningen bieden een oplossing voor de problemen die zich voordoen, een mogelijkheid om het overschrijven lokaal te beperken. Vorzuhängen de eerder gepresenteerde methode, de gewenste modules klassen (prepend), is meestal de veilige versie (en de mogelijkheid biedt ook de gedekte methode om direct aan te roepen).
class Numeriek # ruby-interne klasse
def inverse # nieuwe methode, bereken de reciproke
Eerst 0 / zelf
einde
einde
5 . inverse # => 0.2
Domeinspecifieke taal
Ruby wordt vaak gebruikt om domeinspecifieke talen te maken . Dit zijn tekstmodules die minder op programmacode lijken en meer op een opmaaktaal , maar eigenlijk normale Ruby-code zijn. Dit wordt enerzijds mogelijk gemaakt door de flexibele notatie van Ruby, bijvoorbeeld haakjes na methodeaanroepen of puntkomma's aan het einde van de regel zijn optioneel. Aan de andere kant biedt Ruby veel mogelijkheden voor metaprogrammering , die het mogelijk maken om overbodige uitdrukkingen te laten verdwijnen en het programma achter de schermen te veranderen. Als voorbeeld de configuratie van een testfabriek voor FactoryBot :
Fabrieksbot . definieer doen
fabriek : gebruiker doen
voornaam "Max"
achternaam "Mustermann"
admin false
einde
fabriek : admin , klasse : gebruiker do
voornaam "Beheerder"
achternaam "Root"
beheerder waar
einde
einde
Krachtige standaardbibliotheek
De kernklassen (string, integer, float, array, hash, range, regexp) hebben een schat aan methoden die direct in elk ruby-programma kunnen worden gebruikt. Vooral door het veelvuldig gebruik van blokken kunnen lange programma's met deze methodes worden teruggebracht tot een paar regels, waardoor Ruby zeer geschikt is voor het tonen van proof-of-concepts . Vooral de Enumerable- module, die veel functionele programmeerconcepten rechtstreeks in de Ruby-kern brengt, valt op. Enumerable kan worden geïntegreerd in elk object dat een itereerbare container vertegenwoordigt en elke methode implementeert, bijvoorbeeld de klassen Array, Hash en Range. For-loops zijn daarom meestal niet nodig in Ruby. De hieronder getoonde methoden reduce , count , sort_by , each_slice en map zijn allemaal methoden van Enumerable en kunnen daarom eenvoudig worden toegevoegd aan klassen die u zelf heeft gemaakt.
# tel de getallen 1 tot 100 bij elkaar op (zonder somformule), verkleinen komt overeen met vouwen uit de functionele programmering
( 1 .. 100 ) . verminderen { | teller , nummer | teller + nummer } # (1..100) .som werkt ook
# Array van de getallen van 0 tot 30 in stappen van 5
( 0 .. 30 ) . stap ( 5 ) . naar een
# Aantal regels in een bestand dat leeg is (zonder het bestand volledig in het geheugen te laden)
IO . foreach ( "bestandsnaam" ) . tel { | lijn | regel = ~ / ^ \ s * $ / }
# Sorteer array op lengte van achternaam
[ "Max Mustermann" , "John Doe" , "Tarou Yamada" ]. sort_by { | naam | naam . splitsen . laatste . lengte }
# Zet elk derde woord in de zin met een hoofdletter
"Franz jaagt in compleet vervallen taxi door Beieren." . splitsen . elke_slice ( 3 ) . kaart { | drie_woorden | drie_woorden . laatste . upcase! ; drie_woorden } . afvlakken . meedoen ( " " )
Naast de geïntegreerde modules wordt Ruby standaard met veel modules geleverd. Zo is ondersteuning voor bijvoorbeeld JSON , YAML , HTTP , benchmarks, priemgetallen, beveiligde willekeurige getallen, OpenSSL en logging direct beschikbaar.
Metaprogrammering
Ruby biedt uitgebreide mogelijkheden voor metaprogrammering . Het is dus z. B. mogelijk om methoden te genereren, instantievariabelen uit te wisselen, de overervingshiërarchie te wijzigen of constanten te bewerken. Het is echter niet mogelijk om de syntaxis te wijzigen of extra operators toe te voegen. Een methode voor het automatisch genereren van setters en getters wordt hier als voorbeeld gegeven (reeds in de standaard opgenomen onder de namen attr_reader , attr_writer , attr_accessor ).
class Object # Monkey patchen van alle klassen
def zelf . getter * args # self is Object hier, er wordt een klassenmethode gemaakt
argumenten . elk doen | argument | # doorloopt alle parameters
define_method arg do # define_method (arg) {block} creëert een nieuwe methode met de naam arg met het inhoudsblok
instance_variable_get ( "@ # { arg } " . to_sym ) # instance_variable get geeft de waarde van de instantievariabele van de opgegeven naam
end # \ - "@ # {arg}" plaatst een @ voor de inhoud van arg, to_sym zet de string om in een symbool
einde
einde
def zelf . setter * args # * args verpakt alle parameters in een array genaamd args
argumenten . elk doen | argument |
define_method : " # { arg } =" doe | nieuwe_waarde | # define_method draagt de parameters over die aan het blok zijn doorgegeven
instantie_variabele_set ( "@ # { arg } " . to_sym , new_value ) # \ -setter- methoden eindigen op =
einde
einde
einde
einde
klassenpaar met 2
def initialiseer links # constructor
@links = links # Instantievariabelen worden automatisch gegenereerd wanneer ze in een methode worden vermeld
@rechts = 2
einde
getter: links: rechts
setter : links
einde
paar = paar met2 . new ( 4 ) # new roept altijd de constructor aan
paar . links # => 4
paar . rechts # => 2
paar . links = 9 # => 9
paar . links # => 9
paar . rechts = 8 # => fout: NoMethodError (ongedefinieerde methode `right = ')
Deze technieken zijn ook goed voor het debuggen van applicaties of het analyseren van slecht gedocumenteerde applicaties of bibliotheken. Wanneer bijvoorbeeld de methods
methode wordt aangeroepen, antwoordt elk object met een lijst van al zijn methoden, instance_variables
retourneert een lijst met alle instantievariabelen.
Integratie in Unix
Net als Perl kan Ruby direct worden geïntegreerd in de pijplijn van de Unix-shell. Dit wordt mogelijk gemaakt door de opdrachtregelparameters van de Ruby-interpreter, waarmee de programmalogica en het gebruikelijke programmagedrag kunnen worden gedefinieerd (meestal dezelfde bewerking die op elke regel wordt uitgevoerd). Ruby breidt de standaard Unix-tools uit met geavanceerde methoden voor tekstanalyse en tekstverwerking.
Ruby biedt ook de mogelijkheid om processen gemakkelijk binnen een programma te starten, hun invoer te regelen en uitvoer- en retourwaarden uit te lezen. Code binnen `` wordt direct doorgegeven aan de Unix-shell. Het commando os_string = `uname -a`
de naam van het besturingssysteem rechtstreeks op in een Ruby-variabele. De retourwaarde van de laatste programma-oproep wordt automatisch opgeslagen in de globale variabele $?
opgeslagen. Signaalverwerking, sockets en threads worden ook rechtstreeks ondersteund door de taalkern zonder extra bibliotheken. Om de verwerking te versnellen is er een module in Ruby genaamd FileUtils , die een groot deel van de functionaliteit van veel Unix-bestandsbeheerprogramma 's ( rm , cp , chmod ) rechtstreeks in Ruby in kaart brengt.
Syntaxis en basis
Naamgeving
Ruby volgt de gebruikelijke conventie voor namen van methoden en variabelen, een naam moet beginnen met een kleine letter of een underscore, daarna kunnen eventuele letters (volgens Unicode ), cijfers en underscores volgen. Methoden kunnen ook eindigen met een uitroepteken of vraagteken. Volgens de gebruikelijke conventie dient de eerste als een indicatie dat deze methode een scherpere versie is van dezelfde methode zonder uitroepteken (verandert de status van het object, gooit fouten, ...), de laatste betekent dat de functie retourneert een Boolean (waar of onwaar). Als een variabelenaam met een hoofdletter begint, is het een constante. Variabelen kunnen ook beginnen met een speciaal teken dat het geldigheidsgebied beschrijft.
Identificatie variabele
Ruby onderscheidt vijf geldigheidsgebieden:
- Meestal is een variabele lokaal geldig binnen het omringende blok of de methode.
- Een
@
voor variabelen declareert instantievariabelen, ze worden dan permanent toegewezen aan de instantie en zijn alleen hierin zichtbaar. Instantievariabelen zijn alleen toegankelijk van buitenaf met behulp van methoden. Toegang tot niet-bestaande instantievariabelen geeft geen fout, maar retourneert nul - Een voorafgaande
@@
maakt variabelen klassevariabelen die bij de omringende klasse horen. - Met
$
worden variabelen globaal en zijn dus zichtbaar in het hele programma. - Het geldigheidsbereik voor constanten is afhankelijk van de lokale nestdiepte en kan worden gespecificeerd met
::
Methode-aanroepen en -expressies
In Ruby worden methodeaanroepen niet noodzakelijkerwijs gemarkeerd met de volgende haakjes. gets.chomp
is daarom gelijk aan gets().chomp()
. Als methoden parameters vereisen, moeten deze tussen haakjes worden geplaatst als een andere bewerking op het resultaat moet worden uitgevoerd. "a,b,c".split ","
is ok, "a,b,c".split(",").join(" ")
vereist het eerste "a,b,c".split(",").join(" ")
haakjes. Omdat haakjes ook worden gebruikt voor groeperen, mag er nooit een spatie worden geplaatst tussen de naam van de methode en het haakje wanneer de methode wordt aangeroepen ( [1,2].join␣("|") * 2 != [1,2].join("|") * 2 => [1,2].join(("|") * 2) != ([1,2].join("|")) * 2 => "1||2" != "1|21|2"
).
Elke instructie vormt een uitdrukking die aan een variabele kan worden toegewezen. Afzonderlijke instructies worden gescheiden door regeleinden of puntkomma's. De laatste uitdrukking binnen een methode vormt automatisch de retourwaarde. Het is echter ook mogelijk om eerder terug te springen met het trefwoord return .
Gegevenstypen
De elementaire gegevenstypen hebben handigere constructors dan de gebruikelijke Klasse.new
- Tekenreeks:
"Text"
,'Text'
of%{Text}
tekst - Integer:
3
(tientallensysteem),0775
of0o775
(octaal systeem),0xFF
(hexadecimaal systeem)0b1001
(binair systeem) geheel getal (onbeperkte grootte) - Float:
3.0
drijvende-kommagetal (beperkte precisie) - Rationeel:
1/2r
rationaal getal - Complex:
1 + 1i
complex getal - Array:
[1,2,3]
Verzameling, kan een willekeurig aantal verschillende gegevenstypen bevatten - Hash:
{ 1 => "eins", 2 => "zwei" }
Toewijzing, wijst precies één waarde toe aan elke waarde voor de pijlen (toets) - Regexp:
/\A(eins|zwei)\z/
of%r{\A(eins|zwei)\z}
Reguliere expressie - Bereik:
1..3
of1...4
(exclusief rechter element) interval - Symbool
:zeichen
symbool, zie hieronder
Dynamische snaren
Standaard kunnen tekenreeksen worden gewijzigd in Ruby, dwz dat een String-object zijn waarde tijdens runtime kan wijzigen. text = "Felar"; text[2..3] = "hle"; puts text
verandert de waarde van text
direct (en drukt fouten af ). Veel tekenreeksmethoden zijn beschikbaar, zowel in een wijzigende variant als in een variant die een nieuw tekenreeksobject maakt.
een = "ABC"
b = een . kleine letter
zet a , b # => ABC abc
een . onderkast!
zet a , b # => abc abc
Zoals elk Ruby-object, kunnen strings worden bevroren door de freeze
methode aan te roepen ( "ABC".freeze
) en kunnen ze vervolgens niet worden gewijzigd.
symbolen
Dit ietwat ongebruikelijke en ook controversiële datatype is een soort mengsel van integer en string. Het dient voornamelijk als geheugensteun voor sleutels van hashes, aangezien dynamische strings hier onpraktisch zijn en gehele getallen weinig geheugen nodig hebben. Symbolen hebben niet de tekstmanipulatiemethoden van String, maar kunnen op elk moment naar strings worden geconverteerd. Als symbolen in hashes als sleutels worden gebruikt, kan een vereenvoudigde notatie worden gebruikt. In plaats van { :a => 1, :b => 2 }
kan ook { a: 1, b: 2 }
worden geschreven. Symbolen worden ook intern vaak gebruikt in Ruby, dus methoden kunnen ook worden aangeroepen met hun symboolnaam: 1 < 4
kan ook worden geschreven als 1.send(:<, 4)
. Eenvoudige blokken die slechts één methode van het overgedragen object aanroepen, kunnen op een vereenvoudigde manier worden geschreven met behulp van symbolen, waarbij het symbool de aan te roepen methode aangeeft. [1,2,3].map{|i| i.to_s}
kan ook worden geschreven als [1,2,3].map(&:to_s)
(& zet het symbool om in een blok).
Waarheidswaarden
Er zijn drie verschillende waarheidswaarden in Ruby, true
, false
en nil
. Nil staat voor een ontbrekend resultaat en wordt, net als false, geëvalueerd als false . True en alle andere objecten worden als true geëvalueerd. puts "Ja!" if 0
waar is , wordt "Ja!" uitgevoerd.
Foutafhandeling
In de meeste programmeertalen moet het programmagedeelte dat op fouten moet worden gecontroleerd, expliciet worden gemarkeerd (meestal met behulp van de trefwoorden try and catch ); in Ruby omvat het programmagedeelte in de meest voorkomende gevallen de volledige methode of het hele blok, geen extra gebied moet worden gemarkeerd. Indien een afbakening nodig mocht zijn, kan het gebied worden gemarkeerd met begin en einde .
def give_sum_from arg1 , arg2
# Methode logica
tenzij arg1 . is een? ( Numeriek ) && arg2 . is een? ( Numeriek )
hef ArgumentError op . new ( "Voer alleen cijfers in" ) # raise throws errors
einde
zet arg1 + arg2
redding ArgumentError => e # Catch ArgumentError
zet "Er is een fout opgetreden bij het overzetten van parameters"
redding => e # Vang alle verdere fouten
zet e . bericht
zorg ervoor dat # in ieder geval wordt uitgevoerd
zet 'einde methode'
einde
Alternatieve voorwaarden / lussen
Voorwaarden en lussen bieden zowel postfix-notatie als hun eigen sleutelwoord voor de inverse (geïnspireerd door Perl ).
een = 5
als a < 10 ; zet een ; einde
zet a als een < 10 # achtervoegselvorm
tenzij a > = 10 ; zet een ; einde # inverse
zet a tenzij a > = 10 # inverse + achtervoegselvorm
terwijl een < 10 ; zet een ; een + = 1 ; einde
( zet a ; a + = 1 ) terwijl a < 20 # achtervoegselvorm
tot a > = 30 ; zet een ; een + = 1 ; einde # inverse
( zet a ; a + = 1 ) tot a > = 40 # inverse + achtervoegselvorm
Normale uitdrukkingen
Ruby bevat reguliere expressies direct in de taalkern. Ruby gebruikt zijn eigen regex-engine genaamd Onigmo , waarvan de syntaxis en functionaliteit voor het grootste deel compatibel is met PCRE . Bovendien is het mogelijk om Ruby-variabelen rechtstreeks in reguliere expressies te interpoleren en om elke programmalogica te gebruiken via blokken voor zoeken en vervangen. Het volgende commando telt bijvoorbeeld alle getallen in een tekst met één op: puts "test, 1, 2, 3".gsub(/(\d+)/){|zahl| zahl.to_i + 1} # => test, 2, 3, 4
constanten
In Ruby zijn constanten alle variabelen die beginnen met een hoofdletter. Alle klassen en modules zijn daarom constanten. Het bijzondere aan constanten in Ruby is hun nesting. Constanten binnen constanten kunnen worden aangeroepen met ::
en zijn niet onderworpen aan toegangsrechten (zoals methoden of instantievariabelen). Deswegen können Module als Namensräume benutzt werden, alle Variablen bleiben darin versteckt, auf alle Konstanten (wie bspw. Klassen) kann über den Modulnamen qualifiziert zugegriffen werden (bspw. MeinModul::MeineKlasse.new
).
Bestandteile
Interaktive Ruby-Shell
Interactive Ruby ( irb ) ist eine Read-Eval-Print Loop (REPL), mit welcher der Anwender interaktiv Ruby programmieren kann. Irb wird mit dem Ruby-Interpreter ausgeliefert und kann zum Analysieren und Testen eingesetzt werden:
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
Als Alternative zu Irb gibt es Pry , eine REPL, welche weitaus tiefgreifendere Möglichkeiten zur Introspektion und zum Debuggen mitbringt.
RDoc und ri
RDoc ist ein Software-Dokumentationswerkzeug , welches aus Ruby- und C-Quelltexten automatisch HTML -Dokumentationsdateien erstellt. Weiterhin wird eine Datenbank aufgebaut, die mit dem Tool ri durchsucht werden kann. RDoc und ri sind Bestandteil der Standarddistribution und werden zusammen mit dem Interpreter ausgeliefert.
Rake
Rake steht für Ruby-Make und ist eine Alternative zu Make aus C . Da es in Ruby keine Kompilationsphase gibt, dienen Rakefiles zum Automatisieren repetitiver Aufgaben, bspw. dem Generieren von Dokumentation, dem Upload von Dateien oder dem Packen von Projekten. Rake kann wie Make Abhängigkeiten auflösen, wenn für Aufgabe B erst Aufgabe A erfüllt sein muss, so führt Rake automatisch Aufgabe A aus. Rake ist eine domänenspezifische Sprache , dh, es lässt sich bequem wie eine Auszeichnungssprache lesen, bietet aber die vollen Möglichkeiten die Ruby bietet.
Paketverwaltung
Ruby-Bibliotheken werden üblicherweise als Gems (RubyGems) gepackt und auf rubygems.org, dem zentralen Gem-Register, veröffentlicht. RubyGems löst bei der Installation oder bei Updates die im Paket angegebenen Abhängigkeiten eigenständig rekursiv auf und bietet dabei sogar die Möglichkeit Pakete gleichzeitig in unterschiedlichen Versionen bereitzustellen. Seit Ruby 1.9 ist Rubygems Bestandteil der Standardbibliothek von Ruby. Heute wird es meist zusammen mit Bundler benutzt (ebenfalls Teil der Standardbibliothek, seit Ruby 2.6), einem Programm welches Schnappschüsse aus einer Kollektion von Gems erstellt und diese Anordnung auf anderen Maschinen (oder andern Projektordnern) wiederherstellen kann.
Implementierungen
Referenzimplementierung
Die Referenzimplementierung von Ruby wurde von Yukihiro „Matz“ Matsumoto als Interpreter in C entworfen. Dieser wird meist als MRI (Matz's Ruby Interpreter) oder auch als CRuby bezeichnet und ist derzeit am weitesten verbreitet. Den Kern bildet YARV (Yet Another Ruby VM) , eine virtuelle Maschine . Statt ein Rubyprogramm direkt auszuführen, wird es zunächst in Bytecode übersetzt und dann von YARV interpretiert, wodurch sich ein Geschwindigkeitsvorteil ergibt. Weiterhin enthält diese Version eine leistungsstarke Regexp -Maschine namens Oniguruma und unterstützt Multibyte-Zeichensätze wie UTF-8 .
Der offizielle Interpreter läuft auf den folgenden Betriebssystemen:
- POSIX -kompatible Systeme (ua Linux , BSD und macOS )
- Windows (aktuelle Versionen benötigen MSYS2 und laufen demnach ab Vista )
Alternative Implementierungen
Es gibt zahlreiche alternative Ruby-Implementierungen mit unterschiedlichem Umfang und Zielen:
- JRuby , eine Neuimplementierung des Ruby-Interpreters in Java mit dem Ziel, Ruby nahtlos in die Java-Plattform zu integrieren. JRuby ist fast vollständig kompatibel zu Ruby 2.3. JRuby ist zudem kompatibel zu einigen Ruby-Erweiterungen von Rubinius (Foreign Function Interface, Multi-VM-API), allerdings nicht mit C -Erweiterungen von CRuby.
- Rubinius , eine von Smalltalk-80 inspirierte Implementierung. Abgesehen von der virtuellen Maschine ist Rubinius vollständig in Ruby geschrieben. Rubinius ist nahezu vollständig kompatibel zu Ruby 2.3. Rubinius nutzt die Low Level Virtual Machine (LLVM) und ist kompatibel mit C -Erweiterungen der Referenzimplementierung.
- Mruby ist eine weitere Ruby-Implementierung erschaffen vom Ruby-Schöpfer Yukihiro Matsumoto. Mruby ist eine auf eingebettete Systeme zugeschnittene Version von Ruby, welche sich durch geringen Speicherbedarf und hohe Modularisierung auszeichnet. Mruby stellt nicht die vollständige Funktionalität von CRuby bereit. Mruby kann den Quellcode in Bytecode übersetzen, welcher dann ohne Kompilationsschritt interpretiert oder in C -Programme eingebettet werden kann.
- Opal ist ein Compiler von Ruby nach JavaScript. Es handelt sich um eine Implementierung der Ruby-Corelib und Stdlib, sowie den zugehörige Gems. Mit Opal lassen sich clientseitige Webanwendungen in Ruby realisieren. Es gibt einige Einschränkungen, die der Umsetzung nach JavaScript geschuldet sind.
- TruffleRuby ist eine Ruby-Implementierung die auf der GraalVM läuft. Ziel der Implementierung ist es die Vorteile der GraalVM mittels Ruby nutzbar zu machen. Diese sind Geschwindigkeit (Start- und Laufzeit), Parallelisierung und das kontrollierte Ausführen von C-Erweiterungen. TruffleRuby wird maßgeblich von Oracle entwickelt.
- Fullstaqruby ist eine auf der MRI-basierende Implementierung, die für den Einsatz auf Webservern ausgelegt ist. Im Vergleich zur Referenzimplementierung verspricht Fullstaqruby eine bessere Performance bei geringerem Speicherverbrauch.
Historische Ruby-Implementierungen:
- IronRuby ist eine Implementierung, die Ruby ins .NET Framework integriert und in C# implementiert ist.
Das Projekt ist seit 13. März 2011 inaktiv und wird nicht mehr weiterentwickelt. - Cardinal , ein Interpreter für die virtuelle Maschine Parrot . Das Projekt ist seit Juni 2013 inaktiv.
- MagLev ist eine Implementierung des Unternehmens Gemstone für deren proprietäre Smalltalk VM. Das Projekt ist seit 2015 inaktiv.
- MacRuby ist eine Implementierung in Objective-C von Apple , die bis Version 0.4, wie Ruby 1.9, YARV nutzt, ab Version 0.5 allerdings, wie Rubinius , auf die LLVM setzt. Die Weiterentwicklung wurde mit dem 5. Januar 2015 eingestellt.
- Ruby Enterprise Edition ist eine modifizierte Version der Referenzimplementierung, bei der im Wesentlichen der Garbage Collector neu implementiert wurde. REE ist lediglich mit Ruby 1.8 kompatibel, die aktuellste Version stammt aus dem Jahr 2012.
Die Kompatibilität zur Referenzimplementierung wird durch das RubySpec-Projekt überprüft. Es stellt dabei sowohl eine Testsuite als auch eine Spezifikation für Ruby dar. RubySpec war ursprünglich ein Teil von Rubinius, wurde aber ausgelagert und danach auch von einer Vielzahl anderer Entwickler vorangetrieben. Es wird in vielen Ruby-Implementierungen verwendet.
Mit Hilfe des Ruby Version Managers [9] oder Rbenv [10] besteht die Möglichkeit, mehrere Ruby-Implementierungen und Gem-Versionen parallel zu betreiben.
Ein wichtiges Merkmal der Implementierungen ist, ob sie in der Lage sind, Ruby on Rails auszuführen. Derzeit können dies neben der Referenzimplementierung nur JRuby [11] und Rubinius [12] .
Verbreitung und Einsatz
Ruby ist für alle gängigen Desktop-Betriebssysteme frei erhältlich, in den meisten Linux-Distributionen ist es in den mitgelieferten Paketquellen enthalten, unter macOS sogar vorinstalliert.
Größte Verbreitung findet Ruby im Einsatz als Webserver-Skriptsprache. Das verbreitetste Framework hierbei ist Ruby on Rails , wobei es aber zahlreiche Alternativen verschiedener Größen gibt (bspw. Sinatra und Hanami). Die Liste großer Railsprojekte ist lang, am bekanntesten sind möglicherweise kommerzielle Webseiten wie GitHub , Airbnb oder Shopify oder Gemeinschaftsprojekte wie Diaspora , Redmine und Discourse . In Ruby geschriebene Webtechnologien wie Sass und Haml finden auch außerhalb des Ruby-Ökosystems Verwendung.
Weiter große Verbreitung findet Ruby als Skriptsprache zum Verwalten und Automatisieren von Serveraufgaben, angefangen als Ersatz für komplexere Bash -Skripte, als auch für größere Anwendungen, bspw. Puppet (Serverkonfiguration über das Netzwerk), Metasploit ( Penetrationstests ), YaST ( OpenSUSE -Serveradminstration) und Vagrant (Verwaltung virtueller Maschinen).
Ruby wird wegen der flexiblen Syntax ebenfalls gerne als domänenspezifische Sprache benutzt. Mit mruby gibt es auch eine Ruby-Variante, die sich auf Eingebette Systeme spezialisiert. Vereinzelt wird Ruby auch als Skript-Sprache in Spielen verwendet, bspw. im RPG Maker .
Kritik
Kritik an der Sprache wurde aus verschiedenen Gründen geübt:
- Da Variablen vor Gebrauch nicht deklariert werden müssen, können bei Tippfehlern unerwartete Laufzeitfehler auftreten. Statische Codeanalyse, welche mit Ruby 3.0 hinzugefügt wurde, kann einige dieser Probleme verhindern.
- Metaprogrammierung und Monkeypatching erlauben es einem Codestück, alle Klassen und Objekte des Prozesses, in dem es ausgeführt wird, zu ändern. [13]
Auch an der Referenzimplementierung bemängeln Kritiker mehrere Aspekte:
- YARVs Global Interpreter Lock führt dazu, dass mehrere Threads eines Prozesses nicht gleichzeitig auf verschiedenen Prozessorkernen ausgeführt werden können. [14] [15] Seit Ruby 3.0 gibt es ein alternatives System für Nebenläufigkeit, genannt Ractor , welches ohne GIL auskommt. Allerdings muss vorhandener Code dafür umgeschrieben werden.
Sonstiges
Nutzungsbedingungen
Ruby ist eine freie Software . Deshalb ist es kostenlos nutzbar und im Quelltext verfügbar. Dadurch ergibt sich die Möglichkeit, die Sprache an seine eigenen Bedürfnisse anzupassen oder sie in eigene Programme einzubinden.
Der Interpreter und die Standardbibliothek von Ruby sind grundsätzlich unter den Bedingungen der 2-clause BSD-Lizenz nutzbar. Des Weiteren besteht die Möglichkeit, Ruby unter einer eigenen freien Lizenz zu verwenden. [16] Die Ruby-Lizenz ist GPL-kompatibel und wird von der Free Software Foundation als „frei“ akzeptiert. [17]
Ältere Versionen von Ruby (1.9.2 und früher) verwendeten anstatt der BSD-Lizenz die GPL V2 . Als Begründung für den Wechsel wurden Inkompatibilitäten der alten Lizenzierung mit der GPL V3 angeführt. [18] [19]
RubyForge
RubyForge war ein kollaborativer Filehosting - Dienst für in Ruby geschriebene Softwareprojekte. Er wurde im Jahr 2003 von Ruby Central gestartet, um der Ruby-Community eine Heimat für ihre Open-Source -Projekte zur Verfügung zu stellen.
Am 29. November 2009 wurden dort über 9.300 Projekte und mehr als 94.683 Benutzer geführt [20] , am 15. Mai 2014 wurde der Dienst schließlich eingestellt. [21]
Literatur
Für Programmieranfänger
- Chris Pine: Learn to Program . 2. Auflage. The Pragmatic Bookshelf, Raleigh/ Dallas 2009, ISBN 978-1-934356-36-4 (englisch, Kürzere Version kostenlos online ).
Einstieg für Programmierer
- Peter Cooper: Beginning Ruby. From Novice to Professional . 3. Auflage. Apress, New York City 2016, ISBN 978-1-4842-1279-0 (englisch, Quellcode ).
- Dave Thomas, Chad Fowler, Andy Hunt: Programming Ruby 1.9 & 2.0 . 2. Auflage. The Pragmatic Bookshelf, Raleigh/ Dallas 2013, ISBN 978-1-937785-49-9 (englisch, Errata , Quellcode ).
Vertiefung für Programmierer
- David A. Black: The Well-Grounded Rubyist . 2. Auflage. Manning, Shelter Island 2014, ISBN 978-1-61729-169-2 (englisch, Errata , Quellcode ).
- Hal Fulton, André Arko: The Ruby Way. Solutions and Techniques in Ruby Programming . 3. Auflage. Addison-Wesley, Upper Saddle River, ua 2015, ISBN 978-0-321-71463-3 (englisch, Auszug [PDF]).
Gesamtdarstellungen
- David Flanagan, Yukihiro Matsumoto: Die Programmiersprache Ruby . O'Reilly Media, 2008, ISBN 978-3-89721-874-1
Für Fortgeschrittene
- Lucas Carlson, Leonard Richardson: Ruby Cookbook . O'Reilly Media, 2. Auflage 2015, ISBN 1-4493-7371-2 (englisch)
- Pat Shaughnessy: Ruby Under a Microscope . No Starch Press, 1. Auflage 2013, ISBN 1-59327-527-7 (englisch)
- Russ Olsen: Eloquent Ruby . Addison-Wesley Professional, 2011, ISBN 978-0-321-58410-6 (englisch)
- Russ Olsen: Design Patterns in Ruby . Addison-Wesley Professional, 2007, ISBN 978-0-321-49045-2 (englisch)
Normen und Standards
- ISO/IEC 30170 (englisch; standardisiert Ruby auf über 317 Seiten). Erste Version April 2012.
Weblinks
- Offizielle Website von Ruby
- Zusammenstellung von Tutorials zu Ruby
- Dokumentationssammlung zu Ruby (englisch)
- Linkkatalog zum Thema Ruby bei curlie.org (ehemals DMOZ )
Einzelnachweise
- ↑ www.ruby-lang.org .
- ↑ www.ruby-lang.org .
- ↑ D Programming Language 1.0 , Intro. Digital Mars
- ↑ iso.org
- ↑ RubyConf: History of Ruby
- ↑ Ein Interview mit dem Schöpfer von Ruby
- ↑ About Ruby. Abgerufen am 4. Oktober 2018 .
- ↑ Ruby 1.9 released. Abgerufen am 5. September 2020 (englisch).
- ↑ RVM: Ruby Version Manager – RVM Ruby Version Manager - Documentation. Abgerufen am 4. Oktober 2018 .
- ↑ rbenv/rbenv. Abgerufen am 4. Oktober 2018 (englisch).
- ↑ JRuby Wiki. Abgerufen am 23. Februar 2017 (englisch).
- ↑ Evan Phoenix: Rails on Rubinius. 17. Mai 2008, archiviert vom Original am 22. März 2016 ; abgerufen am 23. Februar 2017 (englisch).
- ↑ Avdi Grimm: Monkeypatching is Destroying Ruby. 23. Februar 2008, abgerufen am 23. Februar 2017 (englisch).
- ↑ infoq.com
- ↑ igvita.com
- ↑ Rubys Lizenzbedingungen. Abgerufen am 23. Februar 2017 .
- ↑ Liste der GPL-kompatiblen Lizenzen. Abgerufen am 23. Februar 2017 .
- ↑ Mailinglistendiskussion zum Lizenzwechsel. Archiviert vom Original am 11. Juni 2015 ; abgerufen am 8. Juli 2012 .
- ↑ Beschluss zum Lizenzwechsel auf dem Ruby Developers Meeting 2010. Abgerufen am 23. Februar 2017 .
- ↑ RubyForge ( Memento vom 31. Mai 2014 im Internet Archive )
- ↑ Twitter-Nachricht von Evan Phoenix. Abgerufen am 28. März 2014 .