Ruby is an interpretive, object-oriented, dynamic type of language. The strategy adopted by Ruby is to find a balance between flexibility and run-time security. With the advent of the rails framework, Ruby also blockbuster around 2006 and also guides people back to the fun of programming. Although Ruby is not as efficient as it can be at execution speed, it makes programmers significantly more efficient at programming. This article describes the basic language features of the Ruby language, including basic syntax and the definition of code blocks and classes.
1. The basic
enter the following command on the Ruby Interaction command Line (>>,=> to the command prompt for the return value; The following will write the => symbol and statement on one line to indicate its return value):
>> puts ' Hello, world '
Hello, world
=> nil
>> language = ' Ruby '
=> ' Ruby '
> > puts "Hello, #{language}"
Hello, Ruby
=> Nil
The code above uses puts output, assigns a value to a variable, and implements a string substitution using the syntax of #{}. This indicates that Ruby is interpreted as executing, that the variables can be initialized and assigned without declaring, and that each ruby code returns a value; a single quotation mark contains a string that indicates that it will be interpreted directly, and the string enclosed in double quotes throws a string substitution.
1.1 Programming model
Ruby is a pure object-oriented language, in Ruby Everything is object, you can use the "." Invoke the method that the object has, you can view the type of object and the supported methods through the class and methods methods, such as 4.class => fixnum,7.methods => ["Inspect", "%", "<<", " Numerator ", ...],false.class => falseclass (square brackets represent arrays).
1.2 Flow control
Conditional judgment has a normal block form, and a simple single-line form; In addition to the common if statement, there are unless statements (equivalent to if not, but more readable). Similarly, loops have normal block form and single-line form. Note: In addition to nil and false, all other values represent true, including 0!
# block Form
if x = = 4
puts ' this is 4. '
End # single-line form
puts ' this is false. ' unless true
x = x + 1 while x < x ' results are
x = x-1 until x = = 1 # The result of X is 1.
Similar to other C-family languages, Ruby's logical Operators and (&&), or (| | ) with short-circuit function, if you want to execute the entire expression, you can use & or |
1.3 Duck Type
Performing 4 + ' four ' will cause a typeerror error, indicating that Ruby is a strongly typed language and will get an error when a type conflict occurs. If a statement is placed in the Def...end function definition, the error is only made when the function is invoked, which means that Ruby does type checking at runtime and not compile time, which is called a dynamic type. Ruby's type system has its own potential advantage that multiple classes do not have to inherit from the same parent class to be used in a "polymorphic" way:
A = [' 100.0]
puts A[0].to_i # =>
puts A[1].to_i # => 100
This is called the "Duck type" (duck typing). The first element of the array is a string type, and the second element is a float type, but the conversion to an integer is to_i. The duck type doesn't care what its intrinsic type is, as long as an object walks like a duck and barks like a duck, it's a duck. In the object-oriented design idea, there is an important principle: the interface coding, not implementation coding. If the duck type is used, the implementation of this principle requires very little extra work and can be done easily.
1.4 function
def Tell_the_truth
true
end
Each function returns the result, and if no return value is explicitly specified, the function returns the value of the expression that was last processed before exiting the function. A function is also an object that can be passed as an argument to another function.
1.5 array
Like Python, ruby arrays are also defined in brackets, such as animals = [' lion ', ' tiger ', ' Bear ']; a negative number subscript can return the reciprocal elements, such as animals[-1] => "Bear" By specifying a Range object to get the elements of a section, such as animals[1..2] => [' Tiger ', ' Bear ']. In addition, array elements can be different, and many arrays are just arrays of arrays. Arrays have an extremely rich API that can be used to implement queues, lists, stacks, collections, and so on.
1.6 Hash List
Numbers = {2 => ' two ', 5 => ' five '}
stuff = {: Array => [1, 2, 3],: String => ' Hi, mom! '}
# Stuff[:string] => "Hi, mom!"
A hash table can take any type of key, the stuff key of the above code is special-it is a symbol (symbol) preceded by a colon identifier. Symbols are useful when naming things and concepts, such as two of the same value strings are physically different, but the same symbol is the same physical object and can be observed by repeatedly calling ' I am string '. object_id and: symbol.object_id. In addition, when the hash table is used as the last parameter of the function, curly braces are optional, such as Tell_the_truth:p rofession =>: lawyer.
2. Object-oriented
2.1 Code block
A code block is a function without a name (an anonymous function) that can be passed as a parameter to a function. The code block is wrapped in curly braces for only one row, and multiple lines are wrapped with do/end and can take several parameters.
3.times {puts ' hehe '} # output 3 rows hehe
[' Lion ', ' tiger ', ' Bear '].each {|animal| puts animal} # output List contents
The times above are actually fixnum type methods, and it is easy to implement such a method yourself:
Class Fixnum
def my_times
i = self while
i > 0
i = i-1
yield
end End
3.my_times {puts ' hehe '} # output 3 rows hehe
This code opens an existing class, adds a custom My_times method to it, and invokes the code block with yield. In Ruby, a code block can be used not only for loops, but also for deferred execution, in which the behavior in a block of code executes only when the associated yield is invoked. Code blocks are flooded with Ruby's various libraries, small to every line of the file, large to complex operations on the collection, and are done by blocks of code.
2.2 Class
Call the class method of an object to see its type, and call superclass to see the parent class of that type. The following illustration shows the inheritance chain of numbers, where the horizontal arrows indicate that the right side is the instantiated object on the left, and the vertical arrows indicate that the bottom inherits from the top. All of Ruby's things have a common ancestor object.
Finally, a complete example--defining a tree--to see how Ruby's classes are defined and used, the points of attention are written in the comments.
Class Tree
# Defines an instance variable, using the attr or attr_accessor keyword, which defines the variable and access variable with the same getter method (that is, read-only), and the latter defines a variable with the same setter method (note that the symbol is used here)
Attr_accessor:children,: Node_name
# Construction Method (constructor must be named Initialize)
def initialize (name, children=[])
@node _name = name
@children = children
end to traverse all nodes and execute blocks of code block, note that the parameter is added with a & means to pass the code block as a closure to function
def visit_all (&block)
Visit &block
Children.each {|c| c.visit_all &block}
End
# Accesses a node and executes code block
def visit ( &block)
Block.call self
end
ruby_tree = tree.new ("Ruby",
[Tree.new ("Reia"),
tree.new ("Macruby")])
# Access to a node
ruby_tree.visit {|node| puts node.node_name}
# Access entire tree
ruby_tree.visit_all {|node| puts ' node: #{ Node.node_name} "}
Let's mention Ruby's naming convention:
(1) class adopts CamelCase naming method
(2) The instance variable (an object has a value) must be preceded by @, and the class variable (a class has a value) must be preceded by a @@
(3) Variable and method names full lowercase using underline naming method, such as Underscore_style
(4) The constants are named with all caps, such as All_caps_style
(5) The functions and methods used for logical tests are generally prefixed with question marks, such as if test?
3. Module and mixing (mixin)
Object-oriented languages use inheritance to propagate behavior to similar objects. If an object is like inheriting multiple behaviors, one approach is to use multiple inheritance, such as C++;java using interfaces to solve the problem, Ruby using module mixin. A module is a collection of functions and constants, and if a module is included in the class, the behavior and constants of the module become part of the class.
# define Modules ToFile module
tofile
# get filename
def filename
"object_name.txt"
end
# Create file
def to_f
file.open (filename, ' W ') {|f| f.write (to_s)} # Note here to_s define elsewhere!
End
# defines the user class class person
include ToFile
attr_accessor:name
def initialize ( Name)
@name = name
end
def to_s the
name end
person.new (' Matz '). To_f # Created a file object_name.txt that contains content Matz
The code above is well understood, but one thing to note: to_s is used in a module, implemented in a class, but the class that implements it is not even defined when the module is defined. This is the essence of the duck type. The ability to write to a file is not related to the class of person (a class should do its own thing), but the actual development requires that the person class be written to the additional functionality of the file, and this mixin can be easily qualified for this requirement.
Ruby has two important mixin: enumerations (enumerable) and comparisons (comparable). To make a class enumerable, you must implement each method, and if you want the class to be comparable, you must implement the <=> (spacecraft) operator (compare a,b two operands, return 1, 0, or 1). Ruby strings can be compared like this: ' Begin ' <=> ' End =>-1. There are a number of useful ways to do arrays:
A = [5, 3, 4, 1]
a.sort => [1, 3, 4, 5] # integers have been implemented by the Fixnum class spacecraft operators, so can be compared sortable
a.any? {|i| i > 4} => True
A.all? {|i| i > 0} => True
a.collect {|i| i * 2} => [6, 8, 2]
a.select {|i| I% 2 = 0} => [4]
A.memb Er? (2) => false
A.inject {|product, i| product * i} => 60 # The first parameter is the result of the last execution of the code block, and if the initial value is not set, the first value of the list is used as the initial value
4. Meta Programming (metaprogramming)
the so-called metaprogramming, the white is "write can write program", which said a bit of a mouthful, the following will be explained through an example.
4.1 Open Class
You can redefine any of the classes in Ruby and extend them any way you want, even to make Ruby completely paralyzed, such as redefining the Class.new method. For the development class, this trade-off is primarily about freedom, the freedom to redefine any class or object, to write code that is straightforward, but also to understand that the greater the freedom, the stronger the capacity, the heavier the burden.
Class Numeric
def inches
self
end
def feet
self * 12.inches
end
def miles
Self * 5280.feet
end
def back
self *-1
end
def forward
self
end
The above code, by opening the numeric class, can use the simplest syntax implementations like this to express the distance in inches: puts 10.miles.back,puts 2.feet.forward.
4.2 Using Method_missing
When Ruby cannot find a method, it invokes a special callback method method_missing display diagnostic information. By overwriting this particular method, you can implement some of the most interesting and powerful features. The following example shows how to implement Roman numerals with simple syntax.
Class Roman
# Overlay self.method_missing method
def self.method_missing name, *args
Roman = name.to_s
roman.gsub! ("IV", "IIII")
roman.gsub! ("IX", "VIIII")
roman.gsub! ("XL", "XXXX")
roman.gsub! ("XC", "lxxxx")
(Roman.count ("I") +
Roman.count ("V") * 5 +
Roman.count ("X") * +
Roman.count ("L"
) * + Roman.count ("C") * * End
puts ROMAN.III # => 3
puts ROMAN.XII # => 12
We don't define any practical methods for the Roman class, but we can already Roman the class to represent any Roman numerals! The principle is to pass the method name and parameter to method_missing execution without finding the definition method. First call to_s to convert the method name to a string, and then the Roman numeral "left minus" special form into the "Right plus" form (easier to count), and finally count the number of symbols and weights.
Of course, such a powerful tool also has its price: it is more difficult to debug because Ruby will never tell you that a method cannot be found. Therefore, method_missing is a double-edged sword, it can make the grammar greatly simplified, but to artificially strengthen the robustness of the program as a prerequisite.
4.3 using modules
Ruby is the most popular metaprogramming method, not a module. The following code describes how to extend a class that can read a CSV file in a modular way.
Module Actsascsv
# Whenever a module is include in another module, the included Method
def self.included (base) of the Include module is invoked
Base.extend Classmethods
End
module classmethods
def acts_as_csv
include Instancemethods
end
module Instancemethods
attr_accessor:headers,: csv_contents
def initialize
read
end
def read
@csv_contents = []
filename = self.class.to_s.downcase + ' txt '
file = file.new (filename)
@headers = File.gets.chomp.split (', ') # String's Chomp method removes the carriage return newline character at the end of the string
File.each do |row|
@csv_contents << row.chomp.split (', ') End end end # end of
module Actsascsv
class Rubycsv # No inheritance, free to add
include Actsascsv
acts_as_csv
end
m = rubycsv.new
puts M.headers.inspect
puts M.csv_contents.inspect
Rubycsv contains actsascsv in the above code, so actsascsv included method, base means that the Rubycsv,actsascsv module adds a unique class method rubycsv to the Acts_as_csv class. This method opens the Rubycsv class again and includes all instance methods in the class. And so on, write a program to write a program (through the module to dynamically add Class method).
Some excellent ruby frameworks, such as builder and ActiveRecord, are especially dependent on metaprogramming to improve readability. With the power of metaprogramming, it is possible to shorten the distance between the correct Ruby syntax and the daily use. Note that everything is serving to improve the readability of your code.
5. Summary
Ruby's Pure object-oriented allows you to work with objects in a consistent way. The duck type implements a more realistic polymorphic design based on the methods available to the object, rather than the inheritance level of the object. Ruby's modules and open classes allow programmers to combine behavior closely into grammar, much beyond the traditional methods and instance variables defined in the class.
Core Advantages:
(1) Elegant grammar and strong flexibility
(2) Script: Ruby is a fantastic scripting language that can do many tasks well. Ruby many syntactic sugars can dramatically increase productivity, with a variety of libraries and gems (Ruby packs) that meet the vast majority of everyday needs.
(3) Web development: Many people learn Ruby in the end to use the Ruby on Rails framework for web development. As an extremely successful MVC framework, it has extensive community support and elegant syntax. Twitter was originally implemented in Ruby, and with Ruby's unparalleled productivity, it was possible to quickly develop a qualifying product that could be marketed.
Deficiencies:
(1) Performance: This is Ruby's biggest weakness. With the development of the Times, Ruby is really faster and faster. Of course, Ruby is the creation goal to improve the programmer's experience, in the performance requirements of the application scenario, performance in exchange for a significant increase in production efficiency is certainly worthwhile.
(2) Concurrent and object-oriented programming: Object-oriented is based on the state packaging a series of behaviors, but usually the state will change. This programming strategy can cause serious problems when concurrency is present in the program.
(3) Type safety: static types provide a complete set of tools that make it easier to construct a syntax tree and thus implement various Ides. Implementing the IDE is much more difficult for a dynamically typed language like Ruby.