Ruby (programming language): Difference between revisions

From Citizendium
Jump to navigation Jump to search
imported>Pat Palmer
m (Text replacement - "JRuby" to "JRuby")
(62 intermediate revisions by 8 users not shown)
Line 1: Line 1:
{{subpages9}}
{{subpages}}
'''Ruby''' is a general-purpose [[computer]] [[programming language]] made available as an open-source project in 1995 by its creator, [[Yukihiro Matsumoto]] (commonly called ''Matz''), a Japanese computer professional with experience in open-source software and familiarity with a wide variety of programming languages.  Matz has closely managed Ruby releases in the years since it first appeared, and by 2007, Ruby has been ranked tenth in usage among all programming languages.  Furthermore, its use is still growing<ref name="tiobe">
{{dambigbox|Ruby (programming language)|Ruby}}
{{Authors|Pat Palmer|others=y}}
'''Ruby''' is a general-purpose [[computer]] [[programming language]] made available as [[Open_source_software|open-source software]] in 1995.  It was created by [[Yukihiro Matsumoto]], (commonly called ''Matz''), a Japanese computer professional familiar with a variety of other programming languages.  Matz has closely managed the Ruby open-source project in the years since it first appeared, and by 2007, Ruby has been ranked tenth in usage among all programming languages.  In 2004, Ruby's place in the U.S. computer industry was boosted by the independent release of [[Ruby on Rails|Rails]], a Ruby-based, open-source [[web application framework]] created in the United States by [[David Heinemeier Hansson]], a Danish developer.  Use of Ruby is still growing<ref name="tiobe">
{{cite web|
{{cite web|
url=http://www.tiobe.com/tpci.htm|
url=http://www.tiobe.com/tpci.htm|
Line 9: Line 11:
</ref>.   
</ref>.   


In 2004, Ruby's place in the U.S. computer industry was boosted by the independent release of [[Ruby on Rails|Rails]], a Ruby-based, open-source [[web application framework]] created in the United States by [[David Heinemeier Hansson]], a Danish developer.  This article is an overview of several often-cited Ruby characteristics, independent of Rails, for which the language is sometimes both praised and criticized.
As of October 2007, ever-improving versions of the official open-source Ruby implementation have been released on several different operating systems. These runtimes are interpreted, rather than compiled, and thus Ruby is not yet considered to be a high-performance platform suitable for some heavy-load, enterprise applications. Ruby implementations have also been developed by other groups, including JRuby (an attempt to port Ruby to the [[Java (programming language)|Java]] platform), and [[Rubinius]] (an interpreter modeled after self-hosting [[Smalltalk]] virtual machines).


==Ruby Implementations==
This article is an overview of several often-cited Ruby characteristics, independent of Rails, for which the language is sometimes both praised and criticized.  Like many "newer" [[programming language|programming languages]] (meaning those created or updated since 1990), Ruby is fully [[object-oriented]] and requires the installation of a [[runtime environment]] or [[virtual machine]] before Ruby programs can be developed or run.


Like many "newer" [[programming language|programming languages]] (meaning those created or updated since 1990), Ruby is fully [[object-oriented]] and  requires the installation of a [[runtime environment]], or [[virtual machine]] before Ruby programs can be developed or run. 
==Status==


As of October 2007, ever-improving versions of the official open-source Ruby implementation have been released on several different operating systems.  These runtimes are interpreted, rather than compiled, and thus Ruby is not yet considered to be a high-performance platform suitable for some heavy-load, enterprise applications.  Ruby implementations have also been developed by other groups, including [[JRuby]] (an attempt to port Ruby to the [[Java (programming language)|Java]] platform), and [[Rubinius]] (an interpreter modeled after self-hosting [[Smalltalk]] virtual machines).
As of 2008, the primary barriers to clinching Ruby as a truly dominant computer programming platform at present (on a par, say, with the [[Java platform]] or the [[.NET_Framework|.NET framework]]) may be twofold: 1) the lack of a standard language specification, and 2) the inability of any development environment to support all the major computing platforms.


As of 2007, no formal written specification has been provided for validating Ruby implementations.  So although Ruby can potentially can be used to create platform-independent programs, Ruby is not currently guaranteed to be identical across platforms, and newer versions are not always upwardly compatible with older versions.  Furthermore, a burgeoning number of books, articles and other documentation are not always in complete agreement about the syntax, semantics, and conventions of the language.  There is widespread agreement that Ruby would benefit from having a formal specification.
In its early years, no formal written specification was provided for validating Ruby implementations.  So although Ruby could potentially be used to create platform-independent programs, Ruby was not currently guaranteed to be identical across platforms, and newer versions were not always upwardly compatible with older versions.  Furthermore, a burgeoning number of books, articles and other documentation were not always in complete agreement about the syntax, semantics, and conventions of the language.  There was, however, widespread agreement that Ruby would benefit from having a formal specification.  In 2011, the language was accepted as a Japanese Industrial Standard (JIS X 3017) in 2012 and an international standard (ISO/IEC 30170). 
 
A plethora of Ruby tools are being developed as [[open source]] software: compilers, test runners, integrated development environments, and bindings to graphical user interface toolkits written in other languages.  These include attempts (supported by [[Sun Microsystems|Sun]] and [[Microsoft]], respectively) to provide a Ruby compiler that targets both the Java virtual machine and the .NET runtime. These tools do not yet appear able to run on all the major computing environments (Linux, Mac OS X, and Windows), partly because many are not yet written in Ruby itself.


==Things people like (and hate) about Ruby==
==Things people like (and hate) about Ruby==
Line 36: Line 40:
# [[closure|closures]]
# [[closure|closures]]
# a relatively permissive syntax, said to be more like the way people think and talk
# a relatively permissive syntax, said to be more like the way people think and talk
# loose typing
# so-called Duck typing, considered convenient for programmers
# good string handling and regular expressions
# good string handling and regular expressions
# extensive libraries for networking and web services
# extensive libraries for networking and web services
Line 42: Line 46:


===Closures===
===Closures===
A full discussion of closures deserves an article of its own but probably cannot be avoided in any serious discussion of Ruby.  Closures are a powerful and complex feature, implemented in their most flexible form in only a few programming languages such as [[Smalltalk]].  With all the precision and politeness ubiquitous in the industry, even the definition of what constitutes a closure has been hotly debated.
Closures are a powerful and complex feature, implemented in their most flexible form in only a few programming languages such as [[Lisp]] and [[Smalltalk]].  A full discussion of closures deserves an article of its own but cannot be avoided in any serious discussion of Ruby, which encourages their widespread useThe definition and importance of closures has been widely debated with all the politeness for which the computer industry is known.  The learning curve for closures appears to be steep enough to cause some dissonance with the common claim that "Ruby makes programming easier".
 
A ''closure'' occurs when a procedure (or a so-called ''block''--an unnamed procedure) is physically situated ''inside'' another procedure, and the inner procedure can be referenced (called) from outside of the enclosing procedure.  In some languages, the inner procedure can only read the variables in the enclosing scope; other languages (including Ruby) allow read/write access.  Closures become really powerful when the inner procedure can be referenced (called) from anywhere else in the code, not just from within the enclosing procedure.  Languages such as C, C++, Java or C#, which implement local variables using stack frames, mostly do not allow procedures to exist inside other procedures.  So-called inner classes in Java and C# are closure-like but are mainly restricted to use as event handlers for the enclosing class.  Ruby allows and encourages unrestricted use of closures.
 
[[JavaScript]] allows its functions to be called from anywhere, in such a way that the function context (surrounding environment) can be passed into the procedure as a parameter.  Many programmers use Javascript for years without becoming aware of this capability.


Closures occur when a procedure (or a so-called ''block''--an unnamed procedure) is physically situated ''inside'' another procedure, and the inner procedure can be referenced (called) from outside of the enclosing procedureIf this occurs, the inner procedure still has access to any "local" variables outside itself but within its enclosing procedure ''despite the outer context in which the call occurs''.  In some languages, the inner procedure can only read the variables in the enclosing scope, whereas in others (such as Ruby), the inner procedure can also change the variables which are outside itself but still in the enclosing procedure.   
Knowing when and how to make use of a true closure--what it can be good for--is neither obvious nor simple to many developers.  Ruby advocates often struggle to illustrate the potential power of closures, which formerly were not required learning for a majority of programmers (to whom they were usually not available anyway).  The often-cited example of closure use in Ruby is the ''.each'' procedure, which provides a more convenient way of iterating through collections than conventional loopingBut sceptics counter that even Java now provides its own very simple syntax for iterating through collections (i.e., the "enhanced for loop").   


Knowing what is meant by the term closure is one thing; knowing when and how to make use of it--what it can be good for--is trickier by far.  Closures have not, perhaps, been considered required learning by a majority of programmers, to whom they were usually not available anyway. Closures are accepted as good style in Ruby, and are heavily encouraged in certain contexts.  The often-cited example of a recommended closure use in Ruby is the .each procedure, whose internal design uses a closure and a yield statement. ".each" provides a more convenient way of iterating through collections than conventional loops.  
A warning written by the [[Gang of Four]] in their influential 1995 [[Design Patterns (book)|Design Patterns]] book hints at the risks of a complex feature such as closures: "Dynamic, highly parameterized software is harder to understand than more static software."<ref name="DesignPattern1">{{cite web|url=http://www.awprofessional.com/title/0201633612|title=Design Patterns: Elements of Reusable Object-Oriented Software (page 21)|publisher=Addison-Wesley|year=2007|accessdate=2007-05-24}}</ref>  


Since the scope rules in languages such as C, C++, Java or C# were traditionally implemented by temporarily growing a stack frame to hold any local, or temporary, variables during a call, these languages typically do not allow closures.  This is another way of saying that (at least usually), procedures may not live inside other proceduresSo-called inner classes in Java and C# are a confusing exception.  Inner classes in Java may seem remarkably like closures in that they can access information in the surrounding class, but in practice, their use is typically limited to handling events for the enclosing class.  This fails to persuade some of the absolute needfulness for closures, because languages such as Java now provide their own extremely simple ways of iterating through collections (i.e., the "enhanced for loop").
Even without the full power of Ruby-style closures, allowing scopes within scopes, which is at least part of what a closure does, may be seen as a hazard for unaware programmersIn a deceptively simple-seeming language such as [[JavaScript]], for example, it is not uncommon for programmers first schooled in Java-like languages to misinterpret the meaning of the ''this'' keyword in an inner procedure in Javascript, not understanding that the function context (meaning of ''this.'') depends on how the function was called rather than on a particular enclosing class definition.


After citing the ubiquitous iteration example, closure advocates often state that closures have many more, powerful uses, but many have trouble explaining, in easily accessible terms, what such uses are.  A famous warning from the seminal 1995 Gang of Four Design Patterns book inevitable comes to mind: ""Dynamic, highly parameterized software is harder to understand
The fact that unaware programmers may hang themselves due to the complexity of a feature is not necessarily a reason to withhold that power from a programmerAdvocates claim the added power and elegance of design is worth added difficulty that results when trying to read somebody else's code that uses closures.
than more static software."<ref name="DesignPattern1">{{cite web|url=http://www.awprofessional.com/title/0201633612|title=Design Patterns: Elements of Reusable Object-Oriented Software (page 21)|publisher=Addison-Wesley|year=2007|accessdate=2007-05-24}}</ref>  Allowing scopes within scopes, which is at least part of what a closure does, has its critics because it can be a hazard for unaware programmers.  In a deceptively simple-seeming language such as [[Javascript]], for example, it is not uncommon for programmers to use a variable defined in an outer scope without realizing the side effects of having done so (i.e., the variable will not be started over from scratch each time the inner procedure is called, but will act like a global variable instead)This is a common source of bugs in so-called [[Ajax]] applications if there is a need to have multiple Ajax (Javascript) calls going on between a web browser and web server simultaneously.


===Permissive syntax===
===Permissive syntax===
Ruby tries to be tolerant of syntax styles from several different programming languages, and this makes it easier for programmers to migrate from those languages into Ruby.  The downside of this is that a programmer who is used to only one form of the syntax will now need to become familiar with both (or multiple) syntactic styles.  This is not an issue when learning to write one's own code, but it becomes apparent when reading code from other people, a common maintenance task for programmers.  In fact, the vast size and permissiveness of Ruby syntax not only creates a larger learning curve than a language with less syntactic options would have, it also makes the creation of development tools more complex.


===Loose typing===
=== Establishing variable types at run-time, and its trade-off ===
Sometimes Ruby is described as being a "dynamic" language, or even a "scripting" language, which appears to refer to the fact it is interpreted rather than compiled.  Ruby does not require variable types to be declared, and instead decides the type based on the kind of thing first assigned to the variable (so-called "duck typing").  This is a trade-off between programmer convenience, as weighed against the increased risk of a run-time error because there was no compile-time type checking.  This is one reason why web application programmers requiring very high reliability might choose a language such as Java over Ruby.


===Strings and regular expressions===
===Strings and regular expressions===
Ruby has a lot of useful, built-in libraries for strings and symbols (which are like "interned" strings in Java or C#).  Ruby also has special syntax allowing the use of "hashes", which are similar to keyword-based collections in Java or C#.


===Networking, including web services===
===Networking, including web services===
The power of Ruby's networking libraries, and its support for SOAP-based web services, equals or surpasses those in Java or C#.


===Calling into the OS===
===Calling into the OS===
This feature may be regarded as a double-edged sword.  On the one hand, it's very helpful to be able to take advantage of operating system facilities to expand the power of the Ruby language. On the other hand, doing so makes code less likely to be portable to another operating system.
On a historic note, Pascal (a once very promising programming language) may have failed to achieve immortality due the inability of programmers to make calls to the underlying operating system without great difficulty.  The designers of Ruby (and other programming languages created after Pascal) have taken this "object lesson" to heart and provided facilities to empower calls into the OS if needed.  It can reasonably be argued that Ruby makes this easier than most other languages at present.


==References==
==References==

Revision as of 08:02, 20 March 2024

This article is developing and not approved.
Main Article
Discussion
Related Articles  [?]
Bibliography  [?]
External Links  [?]
Citable Version  [?]
 
This editable Main Article is under development and subject to a disclaimer.
This article is about Ruby (programming language). For other uses of the term Ruby, please see Ruby (disambiguation).
Authors [about]:
Pat Palmer and others.
CZ is an open collaboration. Please
join in to develop this article!

Ruby is a general-purpose computer programming language made available as open-source software in 1995. It was created by Yukihiro Matsumoto, (commonly called Matz), a Japanese computer professional familiar with a variety of other programming languages. Matz has closely managed the Ruby open-source project in the years since it first appeared, and by 2007, Ruby has been ranked tenth in usage among all programming languages. In 2004, Ruby's place in the U.S. computer industry was boosted by the independent release of Rails, a Ruby-based, open-source web application framework created in the United States by David Heinemeier Hansson, a Danish developer. Use of Ruby is still growing[1].

As of October 2007, ever-improving versions of the official open-source Ruby implementation have been released on several different operating systems. These runtimes are interpreted, rather than compiled, and thus Ruby is not yet considered to be a high-performance platform suitable for some heavy-load, enterprise applications. Ruby implementations have also been developed by other groups, including JRuby (an attempt to port Ruby to the Java platform), and Rubinius (an interpreter modeled after self-hosting Smalltalk virtual machines).

This article is an overview of several often-cited Ruby characteristics, independent of Rails, for which the language is sometimes both praised and criticized. Like many "newer" programming languages (meaning those created or updated since 1990), Ruby is fully object-oriented and requires the installation of a runtime environment or virtual machine before Ruby programs can be developed or run.

Status

As of 2008, the primary barriers to clinching Ruby as a truly dominant computer programming platform at present (on a par, say, with the Java platform or the .NET framework) may be twofold: 1) the lack of a standard language specification, and 2) the inability of any development environment to support all the major computing platforms.

In its early years, no formal written specification was provided for validating Ruby implementations. So although Ruby could potentially be used to create platform-independent programs, Ruby was not currently guaranteed to be identical across platforms, and newer versions were not always upwardly compatible with older versions. Furthermore, a burgeoning number of books, articles and other documentation were not always in complete agreement about the syntax, semantics, and conventions of the language. There was, however, widespread agreement that Ruby would benefit from having a formal specification. In 2011, the language was accepted as a Japanese Industrial Standard (JIS X 3017) in 2012 and an international standard (ISO/IEC 30170).

A plethora of Ruby tools are being developed as open source software: compilers, test runners, integrated development environments, and bindings to graphical user interface toolkits written in other languages. These include attempts (supported by Sun and Microsoft, respectively) to provide a Ruby compiler that targets both the Java virtual machine and the .NET runtime. These tools do not yet appear able to run on all the major computing environments (Linux, Mac OS X, and Windows), partly because many are not yet written in Ruby itself.

Things people like (and hate) about Ruby

Despite performance and cross-version and compatibility concerns, enthusiasts of Ruby wax eloquent in praising the language, including numerous subjective statements such as "it's fun". Something of Ruby's appeal may be seen in the brevity of this Hello World program:

puts "Hello, world"

But simple as it initially may seem, Ruby is described as having hidden depths, largely as a result of its support for a complex and powerful feature called closures. Peter Cooper, author of a 2007 book about Ruby, introduces the language by stating, "Ruby has more in common with more esoteric languages such as Lisp and Smalltalk than with better known languages such as PHP and C++"[2]. Cooper's book, and numerous other sources, list several characteristics of Ruby that may allow programs to be written with more ease, speed and "joy", than with other languages, including:

  1. closures
  2. a relatively permissive syntax, said to be more like the way people think and talk
  3. so-called Duck typing, considered convenient for programmers
  4. good string handling and regular expressions
  5. extensive libraries for networking and web services
  6. powerful support for making calls out to the native operating system if needful

Closures

Closures are a powerful and complex feature, implemented in their most flexible form in only a few programming languages such as Lisp and Smalltalk. A full discussion of closures deserves an article of its own but cannot be avoided in any serious discussion of Ruby, which encourages their widespread use. The definition and importance of closures has been widely debated with all the politeness for which the computer industry is known. The learning curve for closures appears to be steep enough to cause some dissonance with the common claim that "Ruby makes programming easier".

A closure occurs when a procedure (or a so-called block--an unnamed procedure) is physically situated inside another procedure, and the inner procedure can be referenced (called) from outside of the enclosing procedure. In some languages, the inner procedure can only read the variables in the enclosing scope; other languages (including Ruby) allow read/write access. Closures become really powerful when the inner procedure can be referenced (called) from anywhere else in the code, not just from within the enclosing procedure. Languages such as C, C++, Java or C#, which implement local variables using stack frames, mostly do not allow procedures to exist inside other procedures. So-called inner classes in Java and C# are closure-like but are mainly restricted to use as event handlers for the enclosing class. Ruby allows and encourages unrestricted use of closures.

JavaScript allows its functions to be called from anywhere, in such a way that the function context (surrounding environment) can be passed into the procedure as a parameter. Many programmers use Javascript for years without becoming aware of this capability.

Knowing when and how to make use of a true closure--what it can be good for--is neither obvious nor simple to many developers. Ruby advocates often struggle to illustrate the potential power of closures, which formerly were not required learning for a majority of programmers (to whom they were usually not available anyway). The often-cited example of closure use in Ruby is the .each procedure, which provides a more convenient way of iterating through collections than conventional looping. But sceptics counter that even Java now provides its own very simple syntax for iterating through collections (i.e., the "enhanced for loop").

A warning written by the Gang of Four in their influential 1995 Design Patterns book hints at the risks of a complex feature such as closures: "Dynamic, highly parameterized software is harder to understand than more static software."[3]

Even without the full power of Ruby-style closures, allowing scopes within scopes, which is at least part of what a closure does, may be seen as a hazard for unaware programmers. In a deceptively simple-seeming language such as JavaScript, for example, it is not uncommon for programmers first schooled in Java-like languages to misinterpret the meaning of the this keyword in an inner procedure in Javascript, not understanding that the function context (meaning of this.) depends on how the function was called rather than on a particular enclosing class definition.

The fact that unaware programmers may hang themselves due to the complexity of a feature is not necessarily a reason to withhold that power from a programmer. Advocates claim the added power and elegance of design is worth added difficulty that results when trying to read somebody else's code that uses closures.

Permissive syntax

Ruby tries to be tolerant of syntax styles from several different programming languages, and this makes it easier for programmers to migrate from those languages into Ruby. The downside of this is that a programmer who is used to only one form of the syntax will now need to become familiar with both (or multiple) syntactic styles. This is not an issue when learning to write one's own code, but it becomes apparent when reading code from other people, a common maintenance task for programmers. In fact, the vast size and permissiveness of Ruby syntax not only creates a larger learning curve than a language with less syntactic options would have, it also makes the creation of development tools more complex.

Establishing variable types at run-time, and its trade-off

Sometimes Ruby is described as being a "dynamic" language, or even a "scripting" language, which appears to refer to the fact it is interpreted rather than compiled. Ruby does not require variable types to be declared, and instead decides the type based on the kind of thing first assigned to the variable (so-called "duck typing"). This is a trade-off between programmer convenience, as weighed against the increased risk of a run-time error because there was no compile-time type checking. This is one reason why web application programmers requiring very high reliability might choose a language such as Java over Ruby.

Strings and regular expressions

Ruby has a lot of useful, built-in libraries for strings and symbols (which are like "interned" strings in Java or C#). Ruby also has special syntax allowing the use of "hashes", which are similar to keyword-based collections in Java or C#.

Networking, including web services

The power of Ruby's networking libraries, and its support for SOAP-based web services, equals or surpasses those in Java or C#.

Calling into the OS

This feature may be regarded as a double-edged sword. On the one hand, it's very helpful to be able to take advantage of operating system facilities to expand the power of the Ruby language. On the other hand, doing so makes code less likely to be portable to another operating system.

On a historic note, Pascal (a once very promising programming language) may have failed to achieve immortality due the inability of programmers to make calls to the underlying operating system without great difficulty. The designers of Ruby (and other programming languages created after Pascal) have taken this "object lesson" to heart and provided facilities to empower calls into the OS if needed. It can reasonably be argued that Ruby makes this easier than most other languages at present.

References

  1. "TIOBE Programming Community Index". TIOBE Software (2007). Retrieved on 2007-10-10.
  2. "Beginning Ruby: From Novice to Professional". Apress paperback book, Introduction p. xxix (2007). Retrieved on 2007-10-10.
  3. Design Patterns: Elements of Reusable Object-Oriented Software (page 21). Addison-Wesley (2007). Retrieved on 2007-05-24.