Context Navigation


Reserved words in ruby 2.1:

ENCODING def in self
LINE defined? module super
FILE do next then
BEGIN else nil true
END elsif not undef
alias end or unless
and ensure redo until
begin false rescue when
break for retry while
case if return yield
class
#!/usr/bin/env ruby
$SAFE=4# set the security value at the highest prior unless we need more freedom
require'a'# will load a.rb, only one time
load'a.rb'# will load a.rb, every time called this line
#
# Structure
#
# Classes:
classAnimal
# this sets a public id/varible that can be used for our objects,gg
# independently of being or not declared in the class, we can already use them
attr_accessor:lenght,:color# both read and write
attr_reader:lenght,:color# read-only
attr_writer:lenght,:color# write-only (setter)
# this method will be called when creating a new object, it requires
# arguments if we state them
definitialize(given_name="Unknown",given_age)
# the funny here is that if you call "dog = Animal.new(5)", it will
# understand that you are passing the second parameter and set Unknown
# to name automatically
@name=given_name# create variables for the objects that we can use,
# from the given arguments
@age=given_age
# variables with @@ instead of @ are accessible only for classes as a
# whole, not by the instance of the objects, useful for store
# information relevant to all objects of the same class
#
# WARNING: there's an important side-effect behaviour important to consider: http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/
ifdefined?(@@number_of_squares)
# variable already exists for all objects when the first one is created
@@number_of_squares+=1
else
# create the variable first time when the first object is created
@@number_of_squares=1
end
end
defself.count
@@number_of_squares# will return the number of objects when Animal.count is called
end
# this is a simple method, used to perform actions to objects (like a function)
defname
# when calling "dog.name" will return "lassie" for example, "return" is optional
return@name
end
# if you want to set the age in another moment than when initialized, you
# need to use this setter function
defage=(new_age)
# new_age is the parameter given to the call, like "dog.age = 10",
# adding = in the name of the method means that the method is used for
# assign values
@age=new_age
end
defsome_error_handled_case
# raise an error type with a message if a specific case
raiseArgumentError,"Age is too young"if@age<2
end
# using self here is only accessible when calling the class, instead the
# object, like: Animal.show_name
defself.show_name# self acts like an alias to Animal, so: def Animal.show_name ...
putsself# when called, will print "Animal" (class name)
end
# create an alias to whatever thing to another name
aliasshow_namelist_name
private
# things from here only accessible from the object itself (instances)
# calls: method of an object can call its private methods (inside's class code)
# cannot call: dog.method_private
# note: using 'send' you can do it, it invokes methods by name: dog.send(:method_private)
defprivated_area
puts"I will only be shown when another method of this class/object calls this private method"
end
protected
# same as private, but callable from different objects of the same class
# allowing to communicate between them, like for do comparisons between objects
defage_difference_with(other_person)
(self.age-other_person.age).abs
end
# example: fred = Person.new(34) ; chris = Person.new(25) ; puts chris.age_difference_with(fred)
defcompare(c)
ifc.age>age
"The other object's age is bigger."
else
"The other object's age is the same or smaller."
end
# example: chris = Person.new(25) ; marcos = Person.new(34) ; puts chris.compare_age(marcos)
end
# back to the elements of code which are public
public
defsummary
puts"I can be called normally"
end
private:method1,:method2# we can also define them on this way
end
# Inheritance:
# create a superclass called Doctor from the Person's class (inheritance)
classDoctor<Person
# we have already defined the method "name" in the Person's class, so we extend it:
defname
# when we call .name method from a Doctor's object, will append like: "Dr. Name"
# "super" walks in inheritance of the same methods in their parents
"Dr. "+super
end
end
somebody=Person.new("John")
putssomebody.name# John
who=Doctor.new("James")
putswho.name# Dr. James
putswho.instance_variables# @name
#
# Polymorfism:
# - calling the method "talk" in Dogs or Cats they do different things, but
# you can use it in the same way this is very useful when you need to do the
# same action for different objects, for a example a loop of talking animals
#
classDog<Animal
deftalk
puts"Woof!"
end
end
classCat<Animal
deftalk
puts"Meeew"
end
end
#
# Nested classes:
# - useful for improve structure/grouping/dependency
#
classDrawing
classLine
end
classCircle
end
# you can call circle subclasses directly from Drawing too on this way:
defDrawing.give_me_a_circle
Circle.new
end
end
# the way to call a class inside another class is by using ::
# trying to use directly Circle will fail, so:
my_circle=Drawing::Circle.new
#
# Extensions
# - already-defined classes (any of them) can be extended or replaced for
# example to the Fixnum objects we can use .minutes to translate a number to
# minutes
classFixnum
# we can extend any class with improvings or modifications
defminutes
self*60
end
end
# and so we can use now:
puts5.minutes# 300
#
# Modules
#
# They allows to separate things to avoid clashes, similar to classes, but
# they doesn't allows you to instantiate objects, their methods can be
# directly used without the need to create objects, they are more like
# functions that just processes things, let's say toolboxes of features
moduleCountry
classRuler
attr_accessor:name
end
defhello
puts"I can say hello without the need to create an object"
end
end
moduleToolbox
classRuler
attr_accessor:lenght
end
# Mix-in: this will print the name of the class which loaded this module
# useful for introducing methods in other's classes
#
# basically is a method defined outside of any class form, so when
# integrating a module inside an external class it will simply work on it
defclass_name
self.class.to_s
end
end
# direct call of the module with its contents
a=Toolbox::Ruler.new
a.lenght=50
b=Country::Ruler.new
b.name="Ghengis Khan"
# get the module features and directly use it
includeCountry
governor=Ruler.new
# you can use the method hello from the module Country, without the need to
# create or use of objects
hello
#
# Flow examples
#
# loops
loopdo
i+=1
breakifi>100# break da loop
end
while(i==10)
puts"i = 10"
end
until(i>10)
puts"i finally reached 10"
end
# if
if2==1
puts"universe is broken"
end
unless2==2
puts"universe is broken"
end
# case
fruit="orange"
casefruit
when"orange"
color="orange"
when"apple"
color="green"
else
color="unknown"
end
# ternary operator
putsx>10?"higher than 10":"lower or equal to 10"
#
# Structures:
# it is an easy and fast way to define attributes and hold data, same as to
# create an entire class with defined initializators (but without require
# strictly to set all the parameters)
Person=Struct.new(:name,:gender,:age)
fred=Person.new("Fred","male",50)
#
# variable substitution ways:
#
foo="12345678901234567890"
# puts the first 10 chars in different ways:
putsfoo[1,10]
putsfoo[0..9]
putsfoo.slice(0,10)
putsfoo.match("^..........").to_s
#
# Arrays:
#
a=[1,2,3,"four"]
a<<5# append an item
a.push6# append an item
putsa.empty?# false
putsa.include?("four")# true
#
# Hashes (associative arrays)
#
dictionary={'cat'=>'feline animal',
'dog'=>'canine animal',
'tags'=>['books',
'libraries',
'knowledge']}
putsdictionary['cat']# shows description
putsdictionary['tags'].first# shows the first array element for the subarray tags
dictionary.delete("cat")
dictionary.delete_if{|key,value|value=~ /feline/}
#
# Code blocks
#
defeach_vowel
%w{a e i o u}.each{|vowel|yieldvowel}
end
each_vowel{|v|putsv+" is a vowel"}
# the delimiter of "each" can be modified passing an argument like .each(',') or
# changing the input delimiter variable $/
#
# More exactly, yield runs "in the inverse way" including its parameters, what you pass to a call to the function that includes a yield, this is a more clear example:
deftest
yield5
puts"method test"
yield100
end
test{|i|puts"You are in the block #{i}"}
# so you got:
# You are in the block 5
# method test
# You are in the block 100
#
# Errors handling
#
classGetWeb
begin
# block of code where can happen errors
a=(10/0)# if this doesn't works...
rescue=>e
a=10# instead of just exiting we can simply assign a default behaviour and continue
puts"class of exception is: "+e.class.to_s# show some debug reason of our error
end
end
# another example:
data=""
begin
#<..code to retrieve the contents of a Web page..>
#data = <..content of Web page..>
rescueZeroDivisionError
#... code to rescue the zero division exception here ...
rescueYourOwnException
#... code to rescue a different type of exception here ...
rescue
puts"The Web page could not be loaded! Using default data instead."
#data = <..load data from local file..>
end
putsdata
#
# Debug
#
# If you want to run a script in debug mode, "ruby -r debug script.rb", use
# step, break, watch, cont, etc... 
# you can found some basic example in the book "beginning ruby" pag. 190
# Catch & Throw:
# note: catch & throw is useless and confusing, avoid it
# catch & throw works in a similar way as rescue/raise, but using symbols rather than exceptions
catch(:finish)do
1000.timesdo
x=rand(1000)
# we will exit the loop "catch" containing the symbol :finish if we got this case
throw:finishifx==123
end
puts"Generated 1000 random numbers withoutgenerating 123!"
end
# another catch & throw example
defroutine(n)
putsn# final result will produce: 3 2 1 0
throw:doneifn<=0# exit inifite nested loop if case happens
routine(n-1)# nested itself, infinitely
end
catch(:done){routine(3)}
#
# Dynamic Code Execution
#
# executes the code created dynamically
eval"puts 2 + 2"
# similar:
my_number=15
my_code=%Q{#{my_number} * 2}
putseval(my_code)
# String interpolation makes the eval methods powerful tools for generating
# different features on the fly. This ability is a power unseen in the majority
# of programming languages
# - this method adds an accessor to another class,
# dynamically using class_eval and interpolating a name given externally
defadd_accessor_to_person(accessor_name)
Person.class_eval%Q{
 attr_accessor :#{accessor_name}
 }
end
# It’s possible to take the previous example a lot further and add an
# add_accessor method to every class by putting your class_eval cleverness in a
# new method, defined within the Class class (from which all other classes descend):
classClass
defadd_accessor(accessor_name)
self.class_eval%Q{
 attr_accessor :#{accessor_name}
 }
end
end
# You can eval code in instances of objects too:
classMyClass
definitialize
@my_variable='Hello, world!'
end
end
obj=MyClass.new
obj.instance_eval{puts@my_variable}# add extra code to an existing object and execute it
# In the same way you can define methods for existing objects
obj.instance_evaldodefnew_method;puts'born new method in an alive object';end;end
# better way to define a method for an existing object, if you dont want to use
# dynamic code execution of eval
obj.new_methoddodefnew_method;puts'born new method in an alive object';end;end
# example of an "attr_accessor" equivalent writed in dynamic code, which will work in the same way:
classClass
defadd_accessor(accessor_name)
self.class_eval%Q{
 def #{accessor_name}
 @#{accessor_name}
 end
 def #{accessor_name}=(value)
 @#{accessor_name} = value
 end
 }
end
end
# You can use this technique to create a multitude of different "code
# generators" and methods that can act as a "macro" language to perform things
# in Ruby that are otherwise lengthy to type out.
#
# Forks & Processes
#
# process-ID is returned in the parent but 'nil' in the child, use this to
# determine which process a script is in
iffork.nil?
exec"ruby other-file.rb"
end
# fork a child and wait for it
child=forkdo
sleep3
puts"Child says 'hi'!"
end
puts"Waiting for the child process..."
Process.waitchild
puts"All done!"
#
# Unit Testing
#
# - default in stdlib is Minitest, but there's also: rspec, minitest,
# test/unit, minispec, bacon, testrocket... rspec is also very used
# create a method for test it later
classString
deftitleize
# we want to use this method for print results like: "This Is A Test"
self.capitalize
# and we will end later in improving the code like these next commented
# lines, because we haven see that the previous test failed in some cases
#self.gsub(/\b\w/) {|letter| letter.upcase }
#self.gsub(/\s\w/) {|letter| letter.upcase }
#self.gsub(/(\A|\s)\w/) {|letter| letter.upcase }
end
end
puts"this is a test".titleize# this will print "This is a test", but we don't want this result, so for avoid bugs:
# method 1 for testing (manual testing)
# let's add some "assertion" checkers
#
# if our method doesn't give us what we exactly expect, fail
raise"Fail 1"unless"this is a test".titleize=="This Is A Test"
# what happens with numbers? let's add this because this is what we expect in any case
raise"Fail 2"unless"another test 1234".titleize=="Another Test 1234"
# and with other chars like ' ?
raise"Fail 2"unless"We're testing titleize".titleize=="We're Testing Titleize"
# method 2 for testing
require'test/unit'
# there's also "Minitest" (included in stdlib) and "Bacon" for unit testing
classTestTitleize<Test::Unit::TestCase
deftest_basic
assert_equal("This Is A Test","this is a test".titleize)
assert_equal("Another Test 1234","another test 1234".titleize)
assert_equal("We're Testing","we're testing".titleize)
end
end
# method 3 for testing: use Minitest instead, seems like more easier and fast to use option
moduleDataStore::AdapterSpec
it"returns nil for an invalid key"do
@adapter.get(:invalid).must_equalnil
end
it"can set a value"do
@adapter.set(:foo,42)
@adapter.get(:foo).must_equal42
end
end
# from: http://wojtekmach.pl/blog/2013/07/17/sharing-examples-in-minitest/
# more: http://blog.arvidandersson.se/2012/03/28/minimalicous-testing-in-ruby-1-9
#
# Misc
#
# run when finish
at_exit{puts"#{Dir.pwd}"}# enqueue a job for when the application has finished to run
# trap
trap("SIGINT")do
puts"signal INT trapped!, what we should do?"
end
# Using Files
puts"It exists"ifFile.exist?("text.txt")
File.open("text.txt"){|f|putsf.gets}# show file contents (cat)
f=File.new("text.txt","r")
putsf.gets
f.close
data=File.read("text.txt")
array_of_lines=File.readlines("text.txt")
f=File.open("text.txt")
putsf.gets
puts"position in file is: "+f.pos
f.pos=8
puts"position in file has moved to: "+f.pos
f.close# close the file when finish!
# by using File.open in a block, is not needed to close the file when finish
File.open("text.txt","w")do|file|file.puts"Hi"end
# appending
f=File.open"text.txt","a"
f.putsTime.now
f.close
# See the modified time of a file
f=File.mtime"text.txt"
putsf.hour# since the object returned (f) is a Time object, we can treat him as it
#
# Typos / Pitfails
#
# if you put a space before ( it is then not interpreted as arguments, ( needs to be always joint with the call
File.open("text.txt","w")
# if you put more than one space like here it is then interpreted as a(+b)
a+b
#
# Documentation (generating your own)
#
# Similar to doxygen, just write comments using this syntax and by running
# "rdoc file.rb" (or yard?) you will obtain nicely html's generated
#
# In documentations, "Array#sample" means the instance method of a class
#= RDoc Example
#
#== This is a heading
#
#* First item in an outer list
# * First item in an inner list
# * Second item in an inner list
#* Second item in an outer list
# * Only item in this inner list
#
#== This is a second heading
#
#Visit www.rubyinside.com
#
#== Test of text formatting features
#
#Want to see *bold* or _italic_ text? You can even embed
#+text that looks like code+ by surrounding it with plus
#symbols. Indented code will be automatically formatted:
#
# class MyClass
# def method_name
# puts "test"
# end
# end
#
#--
# This section is hidden from RDoc and could contain developer
# notes, private messages between developers, etc.
#++
# RDoc begins processing again here after the ++.
#
# by adding in a class or element "#:nodoc: all" there's no docs generated (for
# the entire class)
# SAFE levels
#
# Value of $SAFE Description
# 0 No restrictions. This is the default safe level.
# 1 Potentially unsafe methods can’t use tainted data. Also, the current
# directory is not added to Ruby’s search path for loading libraries.
# 2 The restrictions of safe level 1, plus Ruby won’t load any external
# program files from globally writable locations in the filesystem. This is to
# prevent attacks where hackers upload malicious code and manipulate existing
# programs to load them. Some potentially dangerous methods are also
# deactivated, such as File#chmod, Kernel#fork, and Process::setpriority.
# 3 The restrictions of level 2, plus newly created objects within the
# program are considered tainted automatically. You also cannot untaint objects.
# 4 The restrictions of level 3, plus nontainted objects created prior to
# the safe level being set cannot be modified. You can use this to set up an
# execution environ- ment in a lower safe mode, and then provide a way to
# continue execution while protecting the original objects and environment.
#
# MORE:
#
# regex:
# Try regular expressions in realtime! http://rubular.com/
#
# references:
# http://www.zenspider.com/Languages/Ruby/QuickRef.html
# http://www.tutorialspoint.com/ruby/ruby_quick_guide.htm
# "Begining Ruby - book": useful classes and methods, errors, regex, variables, etc... from pag. 575
#
# standard lib:
# http://www.ruby-doc.org/stdlib-2.1.0/
Last modified 12 years ago Last modified on Nov 15, 2014, 4:04:41 PM
Note: See TracWiki for help on using the wiki.

AltStyle によって変換されたページ (->オリジナル) /