├── .gitignore
├── .ruby-version
├── README.mkdn
├── Rakefile
├── app
├── controllers
│ ├── application.rb
│ └── learn_controller.rb
└── helpers
│ ├── application_helper.rb
│ └── learn_helper.rb
├── config
├── boot.rb
├── environment.rb
├── environments
│ ├── development.rb
│ ├── production.rb
│ └── test.rb
├── initializers
│ ├── inflections.rb
│ └── mime_types.rb
└── routes.rb
├── doc
└── httpd_conf_changes
├── index.rb
├── lib
├── learn_to_program_tutorial.rb
└── learn_to_program_tutorial
│ ├── arrays.rb
│ ├── beyond.rb
│ ├── blocks_procs.rb
│ ├── classes.rb
│ ├── conversion.rb
│ ├── def_methods.rb
│ ├── flow_control.rb
│ ├── formatting_page.rb
│ ├── learn_to_program.rb
│ ├── letters.rb
│ ├── main.rb
│ ├── menu.rb
│ ├── methods.rb
│ ├── numbers.rb
│ ├── setup.rb
│ └── variables.rb
├── log
└── .gitignore
├── public
├── .htaccess
├── 404.html
├── 422.html
├── 500.html
├── SciTEGlobal.properties
├── dispatch.cgi
├── dispatch.fcgi
├── dispatch.rb
├── favicon.ico
├── images
│ ├── LTP_cover.jpg
│ ├── PoweredByRuby.png
│ ├── fleur_right.gif
│ ├── flowerborder.gif
│ ├── locketLTP.png
│ ├── paper_background.png
│ ├── rails.png
│ ├── shadowS.gif
│ ├── speardown_sm.gif
│ ├── spearup_sm.gif
│ ├── swirly.gif
│ ├── titleLTP.gif
│ └── titleLTP_pt_br.gif
├── robots.txt
├── ruby.properties
└── stylesheets
│ ├── pine.css
│ ├── print.css
│ └── tutorial.css
├── script
├── about
├── console
├── destroy
├── generate
├── performance
│ ├── benchmarker
│ ├── profiler
│ └── request
├── plugin
├── process
│ ├── inspector
│ ├── reaper
│ └── spawner
├── runner
└── server
└── test
├── functional
└── learn_controller_test.rb
└── test_helper.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | tmp
3 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 1.8.7-p375
2 |
3 |
--------------------------------------------------------------------------------
/README.mkdn:
--------------------------------------------------------------------------------
1 | Aprenda a Programar
2 | ==================
3 | Leia a introdução deste projeto em [Aprenda a Programar](http://aprendaaprogramar.rubyonrails.com.br/).
4 |
5 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5 |
6 | require 'rake'
7 | require 'rake/testtask'
8 | require 'rake/rdoctask'
9 |
10 | require 'tasks/rails'
11 |
--------------------------------------------------------------------------------
/app/controllers/application.rb:
--------------------------------------------------------------------------------
1 | # Filters added to this controller apply to all controllers in the application.
2 | # Likewise, all the methods added will be available for all controllers.
3 |
4 | class ApplicationController < ActionController::Base
5 | helper :all # include all helpers, all the time
6 |
7 | # See ActionController::RequestForgeryProtection for details
8 | # Uncomment the :secret if you're not using the cookie session store
9 | protect_from_forgery # :secret => '4e5c7c32a50dfd87987cb232b1cc3de5'
10 | end
11 |
--------------------------------------------------------------------------------
/app/controllers/learn_controller.rb:
--------------------------------------------------------------------------------
1 | class LearnController < ApplicationController
2 | session :off
3 |
4 | def index
5 | # captura a saída
6 | request.cgi.instance_eval do
7 | def out(options = 'text/plain', optional = true)
8 | yield if block_given?
9 | end
10 | end
11 | opt = {}
12 |
13 | # reajusta os parâmetros para passar ao CGI
14 | params.each { |k,v| opt.merge!( k => [v] ) }
15 | unless opt.include?("ShowTutorialCode")
16 | opt.merge!("ShowTutorialCode" => [nil])
17 | end
18 | unless opt.include?("Chapter")
19 | opt.merge!("Chapter" => 13)
20 | end
21 | request.cgi.params = opt
22 |
23 | # redireciona a saída do cgi para a saída do controller
24 | render :text => LearnToProgramTutorial.handle_request(request.cgi), :status => 200, :layout => false
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | # Methods added to this helper will be available to all templates in the application.
2 | module ApplicationHelper
3 | end
4 |
--------------------------------------------------------------------------------
/app/helpers/learn_helper.rb:
--------------------------------------------------------------------------------
1 | module LearnHelper
2 | end
3 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | # Don't change this file!
2 | # Configure your app in config/environment.rb and config/environments/*.rb
3 |
4 | RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
5 |
6 | module Rails
7 | class << self
8 | def boot!
9 | unless booted?
10 | preinitialize
11 | pick_boot.run
12 | end
13 | end
14 |
15 | def booted?
16 | defined? Rails::Initializer
17 | end
18 |
19 | def pick_boot
20 | (vendor_rails? ? VendorBoot : GemBoot).new
21 | end
22 |
23 | def vendor_rails?
24 | File.exist?("#{RAILS_ROOT}/vendor/rails")
25 | end
26 |
27 | # FIXME : Ruby 1.9
28 | def preinitialize
29 | load(preinitializer_path) if File.exists?(preinitializer_path)
30 | end
31 |
32 | def preinitializer_path
33 | "#{RAILS_ROOT}/config/preinitializer.rb"
34 | end
35 | end
36 |
37 | class Boot
38 | def run
39 | load_initializer
40 | Rails::Initializer.run(:set_load_path)
41 | end
42 | end
43 |
44 | class VendorBoot < Boot
45 | def load_initializer
46 | require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
47 | end
48 | end
49 |
50 | class GemBoot < Boot
51 | def load_initializer
52 | self.class.load_rubygems
53 | load_rails_gem
54 | require 'initializer'
55 | end
56 |
57 | def load_rails_gem
58 | if version = self.class.gem_version
59 | gem 'rails', version
60 | else
61 | gem 'rails'
62 | end
63 | rescue Gem::LoadError => load_error
64 | $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
65 | exit 1
66 | end
67 |
68 | class << self
69 | def rubygems_version
70 | Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion
71 | end
72 |
73 | def gem_version
74 | if defined? RAILS_GEM_VERSION
75 | RAILS_GEM_VERSION
76 | elsif ENV.include?('RAILS_GEM_VERSION')
77 | ENV['RAILS_GEM_VERSION']
78 | else
79 | parse_gem_version(read_environment_rb)
80 | end
81 | end
82 |
83 | def load_rubygems
84 | require 'rubygems'
85 |
86 | unless rubygems_version >= '0.9.4'
87 | $stderr.puts %(Rails requires RubyGems >= 0.9.4 (you have #{rubygems_version}). Please `gem update --system` and try again.)
88 | exit 1
89 | end
90 |
91 | rescue LoadError
92 | $stderr.puts %(Rails requires RubyGems >= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org)
93 | exit 1
94 | end
95 |
96 | def parse_gem_version(text)
97 | $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
98 | end
99 |
100 | private
101 | def read_environment_rb
102 | File.read("#{RAILS_ROOT}/config/environment.rb")
103 | end
104 | end
105 | end
106 | end
107 |
108 | # All that for this:
109 | Rails.boot!
110 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file
2 |
3 | # Uncomment below to force Rails into production mode when
4 | # you don't control web/app server and can't set it the proper way
5 | # ENV['RAILS_ENV'] ||= 'production'
6 |
7 | # Specifies gem version of Rails to use when vendor/rails is not present
8 | RAILS_GEM_VERSION = '2.0.5' unless defined? RAILS_GEM_VERSION
9 |
10 | # Bootstrap the Rails environment, frameworks, and default configuration
11 | require File.join(File.dirname(__FILE__), 'boot')
12 |
13 | Rails::Initializer.run do |config|
14 | # Settings in config/environments/* take precedence over those specified here.
15 | # Application configuration should go into files in config/initializers
16 | # -- all .rb files in that directory are automatically loaded.
17 | # See Rails::Configuration for more options.
18 |
19 | # Skip frameworks you're not going to use (only works if using vendor/rails).
20 | # To use Rails without a database, you must remove the Active Record framework
21 | config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
22 |
23 | # Only load the plugins named here, in the order given. By default, all plugins
24 | # in vendor/plugins are loaded in alphabetical order.
25 | # :all can be used as a placeholder for all plugins not explicitly named
26 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
27 |
28 | # Add additional load paths for your own custom dirs
29 | config.load_paths += %W( #{RAILS_ROOT}/lib/learn_to_program_tutorial )
30 |
31 | # Force all environments to use the same logger level
32 | # (by default production uses :info, the others :debug)
33 | # config.log_level = :debug
34 |
35 | # Your secret key for verifying cookie session data integrity.
36 | # If you change this key, all old sessions will become invalid!
37 | # Make sure the secret is at least 30 characters and all random,
38 | # no regular words or you'll be exposed to dictionary attacks.
39 | config.action_controller.session = {
40 | :session_key => '_learn_session',
41 | :secret => '041651ad6dc9bfe12a701d60b0575aa2688ed44df336e1ba9658a932464eda4e5476c53966ac3fdfdf21fc5399053cf3aa40da6bc6ba76c0074f82af4b721661'
42 | }
43 |
44 | # Use the database for sessions instead of the cookie-based default,
45 | # which shouldn't be used to store highly confidential information
46 | # (create the session table with 'rake db:sessions:create')
47 | # config.action_controller.session_store = :active_record_store
48 |
49 | # Use SQL instead of Active Record's schema dumper when creating the test database.
50 | # This is necessary if your schema can't be completely dumped by the schema dumper,
51 | # like if you have constraints or database-specific column types
52 | # config.active_record.schema_format = :sql
53 |
54 | # Activate observers that should always be running
55 | # config.active_record.observers = :cacher, :garbage_collector
56 |
57 | # Make Active Record use UTC-base instead of local time
58 | # config.active_record.default_timezone = :utc
59 | end
60 | require 'learn_to_program_tutorial'
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | # Settings specified here will take precedence over those in config/environment.rb
2 |
3 | # In the development environment your application's code is reloaded on
4 | # every request. This slows down response time but is perfect for development
5 | # since you don't have to restart the webserver when you make code changes.
6 | config.cache_classes = false
7 |
8 | # Log error messages when you accidentally call methods on nil.
9 | config.whiny_nils = true
10 |
11 | # Show full error reports and disable caching
12 | config.action_controller.consider_all_requests_local = true
13 | config.action_view.debug_rjs = true
14 | config.action_controller.perform_caching = false
15 | config.action_view.cache_template_extensions = false
16 |
17 | # Don't care if the mailer can't send
18 | config.action_mailer.raise_delivery_errors = false
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | # Settings specified here will take precedence over those in config/environment.rb
2 |
3 | # The production environment is meant for finished, "live" apps.
4 | # Code is not reloaded between requests
5 | config.cache_classes = true
6 |
7 | # Use a different logger for distributed setups
8 | # config.logger = SyslogLogger.new
9 |
10 | # Full error reports are disabled and caching is turned on
11 | config.action_controller.consider_all_requests_local = false
12 | config.action_controller.perform_caching = true
13 | config.action_view.cache_template_loading = true
14 |
15 | # Enable serving of images, stylesheets, and javascripts from an asset server
16 | # config.action_controller.asset_host = "http://assets.example.com"
17 |
18 | # Disable delivery errors, bad email addresses will be ignored
19 | # config.action_mailer.raise_delivery_errors = false
20 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | # Settings specified here will take precedence over those in config/environment.rb
2 |
3 | # The test environment is used exclusively to run your application's
4 | # test suite. You never need to work with it otherwise. Remember that
5 | # your test database is "scratch space" for the test suite and is wiped
6 | # and recreated between test runs. Don't rely on the data there!
7 | config.cache_classes = true
8 |
9 | # Log error messages when you accidentally call methods on nil.
10 | config.whiny_nils = true
11 |
12 | # Show full error reports and disable caching
13 | config.action_controller.consider_all_requests_local = true
14 | config.action_controller.perform_caching = false
15 |
16 | # Disable request forgery protection in test environment
17 | config.action_controller.allow_forgery_protection = false
18 |
19 | # Tell ActionMailer not to deliver emails to the real world.
20 | # The :test delivery method accumulates sent emails in the
21 | # ActionMailer::Base.deliveries array.
22 | config.action_mailer.delivery_method = :test
23 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format
4 | # (all these examples are active by default):
5 | # Inflector.inflections do |inflect|
6 | # inflect.plural /^(ox)$/i, '\1en'
7 | # inflect.singular /^(ox)en/i, '\1'
8 | # inflect.irregular 'person', 'people'
9 | # inflect.uncountable %w( fish sheep )
10 | # end
11 |
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 | # Mime::Type.register_alias "text/html", :iphone
6 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | ActionController::Routing::Routes.draw do |map|
2 | map.root :controller => 'learn'
3 | map.connect 'index.rb', :controller => 'learn', :action => 'index'
4 | end
5 |
--------------------------------------------------------------------------------
/doc/httpd_conf_changes:
--------------------------------------------------------------------------------
1 | # colocar no seu httpd.conf
2 | # no mac, o path é /private/etc/httpd/users/nome_do_usuario.conf
3 | #
4 | # Alterar LINKADDR no learn_to_program_tutorial.rb de acordo com seu ambiente
5 |
6 | AddHandler cgi-script .rb
7 |
8 |
9 | Options Indexes MultiViews ExecCGI
10 | AllowOverride None
11 | Order allow,deny
12 | Allow from all
13 |
14 |
--------------------------------------------------------------------------------
/index.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require 'cgi'
4 | require 'stringio'
5 | require 'learn_to_program_tutorial'
6 |
7 | cgi = CGI.new
8 |
9 | LearnToProgramTutorial.handle_request cgi
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial.rb:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env ruby
2 |
3 |
4 | #-----------------------------------------------#
5 | # Learn to Program #
6 | # by Chris Pine #
7 | # Copyright (c) 2003-2006 #
8 | # chris@pine.fm #
9 | #-----------------------------------------------#
10 |
11 |
12 | require 'cgi'
13 | require 'stringio'
14 |
15 | Dir.glob(File.dirname(__FILE__) + '/learn_to_program_tutorial/*').each { |file| require_dependency file }
16 |
17 | LINKADDR = '/'
18 | FRLTP_ADDR = 'http://pragmaticprogrammer.com/titles/fr_ltp'
19 |
20 | HLINE = '
'
21 |
22 | # If you decide to change coloring or formatting of this tutorial,
23 | # you'll want to change these to something appropriate.
24 | NUMBER_COLOR = 'verde'
25 | STRING_COLOR = 'vermelho'
26 | KEYWORD_COLOR = 'azul'
27 | INPUT_DESC = 'caixa branca'
28 | OUTPUT_DESC = 'caixa azul'
29 |
30 | # Delimiter for input to sample code, since it comes out
31 | # right alongside the output. Must not be html escapable.
32 | INPUT = "%%%'f'o'o'"
33 |
34 | class LearnToProgramTutorial
35 | @@NUMBER_COLOR = NUMBER_COLOR
36 | @@STRING_COLOR = STRING_COLOR
37 | @@KEYWORD_COLOR = KEYWORD_COLOR
38 | @@INPUT_DESC = INPUT_DESC
39 | @@OUTPUT_DESC = OUTPUT_DESC
40 |
41 | include LearnToProgram
42 | include FormattingPage
43 | include Setup
44 | include Numbers
45 | include Letters
46 | include Variables
47 | include Conversion
48 | include Methods
49 | include FlowControl
50 | include Arrays
51 | include DefMethods
52 | include Classes
53 | include BlocksProcs
54 | include Beyond
55 |
56 | include Menu
57 | include Main
58 | end
59 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/arrays.rb:
--------------------------------------------------------------------------------
1 | module Arrays
2 | #
3 | # ARRAYS AND ITERATORS
4 | #
5 |
6 | def generateArrays
7 | para do <<-END_PARAGRAPH
8 | Vamos escrever um programa que nos permita entrar com quantas
9 | palavras quisermos (uma por linha, até pressionarmos Enter
10 | em uma linha vazia), e depois mostre as palavras em ordem alfabética. Ok?
11 | END_PARAGRAPH
12 | end
13 | para do <<-END_PARAGRAPH
14 | Então... primeiro nós iremos.. bem.. hum... Bom, poderíamos.. rsrsrs..
15 | END_PARAGRAPH
16 | end
17 | para do <<-END_PARAGRAPH
18 | Certo, não sei se podemos fazer isso. Precisamos de uma forma de armazenar
19 | um número qualquer de palavras, e de podermos acessá-las sem que se misturem
20 | com as outras variáveis. Precisamos colocá-las num tipo de lista. Precisamos
21 | dos arrays.
22 | END_PARAGRAPH
23 | end
24 | para do <<-END_PARAGRAPH
25 | Um array é apenas uma lista em seu computador. Cada item da lista
26 | se comporta como uma variável: você pode ver qual objeto um item está
27 | apontando, e você pode fazê-lo apontar para um outro objeto.
28 | Vamos dar uma olhada em alguns arrays:
29 | END_PARAGRAPH
30 | end
31 | prog false do <<-END_CODE
32 | []
33 | [5]
34 | ['Olá', 'Tchau']
35 |
36 | sabor = 'baunilha' # isto não é um array, claro...
37 | [89.9, sabor, [true, false]] # ...mas isto é.
38 | END_CODE
39 | end
40 | para do <<-END_PARAGRAPH
41 | Primeiro nós temos um array vazio, então um array contendo
42 | um único número, então um array contendo duas strings.
43 | Depois, temos uma atribuição simples; e aí um array
44 | contendo três objetos, sendo que o último é um outro
45 | array #{code '[true, false]'}. Lembre-se, variáveis não
46 | são objetos, então, nosso último array está realmente
47 | apontando a para um float, uma string e um array.
48 | Mesmo que nós mudássemos o valor de #{code 'sabor'}, isso
49 | não mudaria o array.
50 | END_PARAGRAPH
51 | end
52 | para do <<-END_PARAGRAPH
53 | Para nos ajudar a encontrar um objeto qualquer num array,
54 | cada item tem um número de indexação. Programadores (e, aliás,
55 | a maioria dos matemáticos) iniciam contando do zero, então,
56 | o primeiro item do array é o item zero. Veja como podemos
57 | referenciar os objetos em um array:
58 | END_PARAGRAPH
59 | end
60 | prog do <<-END_CODE
61 | nomes = ['Ana', 'Maria', 'Cris']
62 |
63 | puts nomes
64 | puts nomes[0]
65 | puts nomes[1]
66 | puts nomes[2]
67 | puts nomes[3] # Isto está fora do intervalo
68 | END_CODE
69 | end
70 | para do <<-END_PARAGRAPH
71 | Vemos então, que #{code 'puts nomes'} imprime cada nome do
72 | array #{code 'nomes'}. Então usamos #{code 'puts nomes[0]'}
73 | para imprimir o "primeiro" nome do array e #{code 'puts nomes[1]'}
74 | para imprimir o "segundo"... Tenho certeza que parece confuso,
75 | mas você deve se acostumar com isso. Você deve realmente
76 | começar a acreditar que contar inicia do zero e parar
77 | de usar palavras como "primeiro" e "segundo".
78 | Se você for num rodízio de pizza, não fale sobre o "primeiro"
79 | pedaço; fale sobre o pedaço zero (e na sua cabeça
80 | pense #{code 'pedaco[0]'}).
81 | Você tem 5 dedos na sua mão e seus números são 0, 1, 2, 3 e 4.
82 | Minha esposa e eu somos malabariastas. Quando fazemos malabares
83 | com 6 pinos, estamos equilibrando os pinos 0 a 5. Felizmente,
84 | em alguns meses, estaremos equilibrando o pino 6 (e portanto,
85 | equilibrando 7 pinos). Você saberá que conseguiu quando
86 | começar a usar o termo "zerésimo" :-) Sim, é uma palavra real..
87 | Pergunte a um programador ou matemático..
88 | END_PARAGRAPH
89 | end
90 | para do <<-END_PARAGRAPH
91 | Finalmente, nós tentamos #{code 'puts nomes[3]'}, apenas veja o que
92 | aconteceria. Você estava esperando um erro? Algumas vezes quando
93 | você faz uma pergunta, sua pergunta não faz sentido (pelo
94 | menos para seu computador); é quando obtém um erro.
95 | Algumas vezes, entretanto, você pode fazer uma pergunta e a resposta
96 | é nada. O que está na posição três? Nada.
97 | O que é #{code 'nomes[3]'}? #{code 'nil'}: A maneira Ruby
98 | de dizer "nada". #{code 'nil'} é um objeto especial
99 | que basicamente significa "não é qualquer outro objeto."
100 | END_PARAGRAPH
101 | end
102 | para do <<-END_PARAGRAPH
103 | Se toda esta numeração divertida de posições de array está confundindo
104 | você, não tema! Freqüentemente, nós podemos evitá-la completamente
105 | usando vários métodos de array, como este:
106 | END_PARAGRAPH
107 | end
108 | h2 {"O Método #{code 'each'}"}
109 | para do <<-END_PARAGRAPH
110 | #{code 'each'} nos permite fazer algo (o que quer que nós
111 | desejemos) para #{code 'each'} (cada em português) objeto pertencente ao array. Assim, se nós
112 | quiséssemos dizer algo bom sobre cada linguagem no array
113 | abaixo, nós faríamos isto:
114 | END_PARAGRAPH
115 | end
116 | prog do <<-END_CODE
117 | linguagens = ['Português', 'Inglês', 'Ruby']
118 |
119 | linguagens.each do |ling|
120 | puts 'Eu adoro ' + ling + '!'
121 | puts 'Você não?'
122 | end
123 |
124 | puts 'E vamos ouví-lo sobre C++!'
125 | puts '...'
126 | END_CODE
127 | end
128 | para do <<-END_PARAGRAPH
129 | Então, o que aconteceu? Bem, nós fomos capazes de passar por
130 | todos os objetos no array sem usar nenhum número, e
131 | isto é muito bom. Traduzindo para o português, o programa
132 | acima seria algo como: Para #{code 'cada'} objeto
133 | em #{code 'linguagens'}, aponte a variável #{code 'ling'}
134 | para o objeto e então #{code 'faça'} (do em inglês) tudo que eu disser,
135 | até que você chegue ao #{code 'fim'} (end em inglês). (Como você sabe,
136 | C++ é uma outra linguagem de programação. É muito mais difícil de aprender
137 | do que Ruby; normalmente, um programa C++ será muitas vezes
138 | maior do que um programa Ruby que faz a mesma coisa.)
139 | END_PARAGRAPH
140 | end
141 | para do <<-END_PARAGRAPH
142 | Vocês poderiam estar pensando consigo mesmos, "Isto é muito parecido
143 | com os laços de repetição (loops) que nós aprendemos anteriormente." Sim, é similar.
144 | Uma diferença importante é que o método #{code 'each'}
145 | é apenas: um método. #{code 'while'} e #{code 'end'}
146 | (como #{code 'do'}, #{code 'if'}, #{code 'else'}, e todas as outras palavras em
147 | #{KEYWORD_COLOR})
148 | não são métodos. Elas são parte fundamental da linguagem
149 | Ruby, como #{code '='} e os parênteses; como os sinais
150 | de pontuações no português.
151 | END_PARAGRAPH
152 | end
153 | para do <<-END_PARAGRAPH
154 | Mas não #{code 'each'}; #{code 'each'} é um apenas um outro
155 | método do array. Métodos como #{code 'each'} que "atuam como"
156 | loops são freqüentemente chamados iteradores.
157 | END_PARAGRAPH
158 | end
159 | para do <<-END_PARAGRAPH
160 | Uma coisa para notar sobre iteradores é que eles são
161 | sempre seguidos por #{code 'do'}...#{code 'end'}.
162 | #{code 'while'} e #{code 'if'} nunca têm um #{code 'do'}
163 | perto deles; nós apenas usamos #{code 'do'} com iteradores.
164 | END_PARAGRAPH
165 | end
166 | para do <<-END_PARAGRAPH
167 | Aqui está um outro atraente iteradorzinho, mas não é um
168 | método de array... é um método de inteiros!
169 | END_PARAGRAPH
170 | end
171 | prog do <<-END_CODE
172 | 3.times do
173 | puts 'Hip-Hip-Urra!'
174 | end
175 | END_CODE
176 | end
177 | h2 {'Mais Métodos de Array'}
178 | para do <<-END_PARAGRAPH
179 | Então nós aprendemos #{code 'each'},
180 | mas existem muitos outros métodos de array... quase tantos
181 | quantos existem métodos de string! Na verdade, alguns
182 | deles (como #{code 'length'}, #{code 'reverse'},
183 | #{code '+'}, e #{code '*'})
184 | funcionam da mesma forma que funcionam para strings, exceto que eles
185 | operam em posições de array ao invés de em
186 | letras de string. Outros, como #{code 'last'}
187 | e #{code 'join'}, são específicos para arrays. Ainda
188 | outros, como #{code 'push'} e #{code 'pop'},
189 | na verdade modificam o array. E assim como com
190 | os métodos de string, você não tem que se lembrar de
191 | todos estes, desde que você possa se lembrar onde
192 | achar informações sobre eles (bem aqui).
193 | END_PARAGRAPH
194 | end
195 | para do <<-END_PARAGRAPH
196 | Primeiro, vamos dar uma olhada em #{code 'to_s'} e #{code 'join'}.
197 | #{code 'join'} funciona de forma semelhante a #{code 'to_s'}, exceto
198 | que ele adiciona uma string entre os objetos do array.
199 | Vamos dar uma olhada:
200 | END_PARAGRAPH
201 | end
202 | prog do <<-END_CODE
203 | comidas = ['feijoada', 'tapioca', 'bolo de fubá']
204 |
205 | puts comidas
206 | puts
207 | puts comidas.to_s
208 | puts
209 | puts comidas.join(', ')
210 | puts
211 | puts comidas.join(' :) ') + ' 8)'
212 |
213 | 200.times do
214 | puts []
215 | end
216 | END_CODE
217 | end
218 | para do <<-END_PARAGRAPH
219 | Como você pode ver, #{code 'puts'} trata os arrays diferentemente
220 | de outros objetos: ele apenas chama #{code 'puts'} em cada um
221 | dos objetos no array. É por isso que chamar #{code 'puts'} para um
222 | um array vazio 200 vezes não faz nada; o array não aponta
223 | para nada, assim não há nada para o #{code 'puts'} mostrar (Fazer
224 | nada 200 vezes ainda é fazer nada).
225 | Tente chamar #{code 'puts'} para um array contendo outros arrays;
226 | fez o que você esperava?
227 | END_PARAGRAPH
228 | end
229 | para do <<-END_PARAGRAPH
230 | Você também notou que eu deixei uma string vazia quando
231 | eu quis #{code 'mostrar'} uma linha em branco? Isto faz a mesma
232 | coisa.
233 | END_PARAGRAPH
234 | end
235 | para do <<-END_PARAGRAPH
236 | Agora vamos dar uma olhada em #{code 'push'}, #{code 'pop'},
237 | e #{code 'last'}. Os métodos #{code 'push'} e #{code 'pop'}
238 | são de alguma forma opostos,
239 | assim como #{code '+'} e #{code '-'} são. #{code 'push'} adiciona
240 | um objeto no fim do seu array, e #{code 'pop'}
241 | remove o último objeto do array (e diz para você
242 | qual era este objeto). #{code 'last'} é similar a #{code 'pop'}
243 | em dizer para você o que está no fim do array,
244 | exceto que o #{code 'last'} deixa o array em paz.
245 | Novamente, #{code 'push'} e #{code 'pop'} realmente
246 | modificam o array:
247 | END_PARAGRAPH
248 | end
249 | prog do <<-END_CODE
250 | favoritos = []
251 | favoritos.push 'azul e branco'
252 | favoritos.push 'verde e amarelo'
253 |
254 | puts favoritos[0]
255 | puts favoritos.last
256 | puts favoritos.length
257 |
258 | puts favoritos.pop
259 | puts favoritos
260 | puts favoritos.length
261 | END_CODE
262 | end
263 | h2 {'Algumas Coisas para Tentar'}
264 | para do <<-END_PARAGRAPH
265 | • Escreva o programa que nós comentamos no início
266 | deste capítulo.
267 | Dica: Existe um adorável
268 | método de array que dará a você uma versão ordenada de um
269 | array: #{code 'sort'}. Use-o!
270 | END_PARAGRAPH
271 | end
272 | para do <<-END_PARAGRAPH
273 | • Tente escrever o programa acima sem usar
274 | o método #{code 'sort'}. Uma grande parte da programação é
275 | resolver problemas, assim pratique o máximo que você puder!
276 | END_PARAGRAPH
277 | end
278 | para do <<-END_PARAGRAPH
279 | • Re-escreva seu programa de Tabela de Conteúdos (do capítulo
280 | #{makeLink 'métodos', :generateMethods}). Inicie o programa
281 | com um array que mantém todas as informações sobre sua Tabela
282 | de Conteúdos (nomes de capítulos, números de páginas, etc.). Então imprima
283 | na tela a informação do array em uma Tabela de Conteúdos,
284 | formatada de forma bem bonita.
285 | END_PARAGRAPH
286 | end
287 | para do <<-END_PARAGRAPH
288 | Até o momento aprendemos bastante sobre um número de métodos diferentes.
289 | Agora é hora de aprender como
290 | #{makeLink 'fazer seus próprios métodos', :generateDefMethod}.
291 | END_PARAGRAPH
292 | end
293 | end
294 | end
295 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/beyond.rb:
--------------------------------------------------------------------------------
1 | module Beyond
2 | #
3 | # BEYOND THIS TUTORIAL
4 | #
5 |
6 | def generateBeyond
7 | para do <<-END_PARAGRAPH
8 | Então, onde é que podemos ir agora? Se você tiver uma pergunta,
9 | para quem pode perguntar?
10 | E se você quer que seu programa abra uma página da Web, envie um e-mail,
11 | ou redimensione uma foto digital?
12 | Pois bem, há muitos, muitos lugares onde encontrar ajuda para Ruby.
13 | Infelizmente, essa resposta não tem muita utilidade, não é? :-)
14 | END_PARAGRAPH
15 | end
16 | para do <<-END_PARAGRAPH
17 | Para mim, realmente existem apenas três lugares onde procuro para ajuda
18 | para o Ruby.
19 | Se for uma pequena questão e eu acho que posso experimentar sozinho para
20 | encontrar a resposta, uso irb.
21 | Se for uma questão maior, procuro no meu Pickaxe.
22 | E se simplesmente não consigo dar conta do recado, então peço ajuda na
23 | lista ruby-talk.
24 | END_PARAGRAPH
25 | end
26 | h2 {'IRB: Ruby interativo'}
27 | para do <<-END_PARAGRAPH
28 | Se você instalou Ruby, então você instalou irb. Para usá-lo, basta ir
29 | ao seu prompt de comando e digitar #{input 'irb'}.
30 | Quando você estiver em irb, você pode digitar qualquer expressão ruby
31 | que você queira, e ele devolverá o valor da mesma.
32 | Digite #{input '1 + 2'}, e devolverá #{output '3'}.
33 | (Note que você não precisa usar #{code 'puts'}).
34 | É como uma espécie de calculadora Ruby gigante. Quando tiver concluído,
35 | digite simplesmente #{input 'exit'}.
36 | END_PARAGRAPH
37 | end
38 | para do <<-END_PARAGRAPH
39 | Há muito mais do que isso a respeito do irb, mas você pode aprender
40 | tudo sobre ele no Pickaxe.
41 | END_PARAGRAPH
42 | end
43 | h2 {'O Pickaxe: "Programming Ruby"'}
44 | para do <<-END_PARAGRAPH
45 | O livro sobre Ruby que você não pode perder de jeito nenhum é
46 | "Programming Ruby, The Pragmatic Programmer's Guide",
47 | de Andrew Hunt e David Thomas (os Programadores Pragmáticos).
48 | Embora eu recomende fortemente a
49 | 2ª edição
50 | deste livro excelente, com a cobertura de todas as últimas novidades do Ruby,
51 | você também pode obter uma versão on-line grátis de pouco mais antiga (mas ainda relevante).
52 | (Na verdade, se você instalou a versão do Ruby para Windows, você já tem ela).
53 | END_PARAGRAPH
54 | end
55 | para do <<-END_PARAGRAPH
56 | Você pode encontrar praticamente tudo sobre Ruby, do básico ao avançado,
57 | neste livro. É fácil de ler; é abrangente; é quase perfeito. Eu gostaria
58 | que todas as linguagens (de programação) tivessem um livro desse nível.
59 | Na parte final do livro, você encontrará uma enorme seção detalhando
60 | cada método de cada classe, explicando-o e dando exemplos.
61 | Eu simplesmente amo este livro!
62 | END_PARAGRAPH
63 | end
64 | para do <<-END_PARAGRAPH
65 | Há um sem número de lugares onde você pode obtê-lo (incluindo o próprio
66 | site do Pragmatic Programmers), mas o meu lugar favorito é no
67 | ruby-doc.org.
68 | Esta versão tem um bom índice , bem como um índice remessivo
69 | (no ruby-doc.org tem muitas outras ótimas documentações, tais como a
70 | API Central (Core API) e a Biblioteca Padrão (Standard Library)...
71 | Basicamente, isso documenta tudo que vem com o Ruby.
72 | Verifique.).
73 | END_PARAGRAPH
74 | end
75 | para do <<-END_PARAGRAPH
76 | E por que é chamado de "o Pickaxe" (picareta)?
77 | Pois bem, há uma imagem de uma picareta na capa do livro.
78 | É um nome bobo, eu acho, mas pegou.
79 | END_PARAGRAPH
80 | end
81 | h2 {'Ruby-Talk: uma lista de discussão sobre Ruby'}
82 | para do <<-END_PARAGRAPH
83 | Mesmo com o irb e o Pickaxe, às vezes você ainda pode não dar conta sozinho.
84 | Ou talvez você queira saber se alguém já fez o que você está fazendo,
85 | para ver se você pode utilizá-lo.
86 | Nestes casos, o melhor lugar é ruby-talk, a lista de discussão do Ruby.
87 | É cheia de gente amigável, inteligente, colaborativa.
88 | Para saber mais sobre ela, ou para se inscrever, procure
89 | aqui.
90 | END_PARAGRAPH
91 | end
92 | para do <<-END_PARAGRAPH
93 | ATENÇÃO: Existe um grande número de e-mails
94 | na lista todos os dias. Eu criei uma regra no meu cliente de e-mail
95 | para que não fique tudo na mesma pasta. Mas se você não quiser ter
96 | que fazer isso, você não precisa!
97 | A lista de discussão ruby-talk tem um espelho no grupo de notícias
98 | comp.lang.ruby, assim, você pode ver as mensagens por lá. Em suma,
99 | você verá as mesmas mensagens, mas de uma maneira um pouco diferente.
100 | END_PARAGRAPH
101 | end
102 | h2 {'Tim Toady'}
103 | para do <<-END_PARAGRAPH
104 | Tenho tentado proteger você de algo com o que vai esbarrar em breve,
105 | é o conceito de TMTOWTDI (pronunciado como "Tim Toady"): There's More
106 | Than One Way To Do It (Há Mais De Uma Maneira Para Fazer Isso).
107 | END_PARAGRAPH
108 | end
109 | para do <<-END_PARAGRAPH
110 | Agora alguns vão lhe dizer que TMTOWTDI é uma coisa maravilhosa,
111 | enquanto outros se sentem bastante diferente.
112 | Eu realmente não tenho fortes sentimentos sobre o assunto em geral,
113 | mas eu acho que é uma péssima maneira de ensinar para alguém como programar.
114 | (Como se aprender uma maneira de fazer alguma coisa não fosse
115 | suficientemente desafiante e confuso!).
116 | END_PARAGRAPH
117 | end
118 | para do <<-END_PARAGRAPH
119 | No entanto, agora que você está indo além deste tutorial, você verá
120 | muito código diversificado. Por exemplo, posso pensar em pelo menos
121 | cinco outras maneiras de criar uma string (além de circundar algum
122 | texto com aspas simples), e cada um deles funciona de maneira um pouco
123 | diferente. Eu só lhe mostrei o mais simples dos seis.
124 | END_PARAGRAPH
125 | end
126 | para do <<-END_PARAGRAPH
127 | E quando conversamos sobre ramificações, mostrei para você
128 | #{code 'if'}, mas não lhe mostrei #{code 'unless'}.
129 | Eu vou deixá-lo entender isso no irb.
130 | END_PARAGRAPH
131 | end
132 | para do <<-END_PARAGRAPH
133 | Outro agradável atalho que você pode usar com #{code 'if'},
134 | #{code 'unless'}, #{code 'while'}, é a elegante versão de uma linha:
135 | END_PARAGRAPH
136 | end
137 | prog do <<-END_CODE
138 | # Estas palavras são de um programa que escrevi para gerar
139 | # baboseiras em inglês. Bacana, não?
140 | puts 'grobably combergearl kitatently thememberate' if 5 == 2**2 + 1**1
141 | puts 'enlestrationshifter supposine follutify blace' unless 'Chris'.length == 5
142 | END_CODE
143 | end
144 | para do <<-END_PARAGRAPH
145 | E, finalmente, há uma outra forma de escrever métodos que recebem blocos
146 | (não procs). Vimos isso onde recebemos o bloco e o transformamos em uma
147 | proc usando o truque do #{code '&block'} na lista de parâmetros quando
148 | se define a função. Depois, para chamar o bloco, você usa
149 | #{code 'block.call'}. Pois bem, há um caminho mais curto (embora
150 | pessoalmente eu o julgue mais confuso). Em vez disto:
151 | END_PARAGRAPH
152 | end
153 | prog do <<-END_CODE
154 | def facaDuasVezes(&bloco)
155 | bloco.call
156 | bloco.call
157 | end
158 |
159 | facaDuasVezes do
160 | puts 'murditivent flavitemphan siresent litics'
161 | end
162 | END_CODE
163 | end
164 | para do <<-END_PARAGRAPH
165 | ...você faz isso:
166 | END_PARAGRAPH
167 | end
168 | prog do <<-END_CODE
169 | def facaDuasVezes
170 | yield
171 | yield
172 | end
173 |
174 | facaDuasVezes do
175 | puts 'buritiate mustripe lablic acticise'
176 | end
177 | END_CODE
178 | end
179 | para do <<-END_PARAGRAPH
180 | Não sei ... O que você acha? Talvez seja eu, mas... #{code 'yield'}?!
181 | Se fosse algo como #{code 'chame_o_bloco_escondido'} (#{code 'call_the_hidden_block'})
182 | ou algo assim, faria muito mais sentido para mim. Muitas pessoas dizem que
183 | #{code 'yield'} faz sentido para elas. Mas acho que esse é o propósito de
184 | TMTOWTDI: elas fazem do jeito delas, e eu vou fazer à minha maneira.
185 | END_PARAGRAPH
186 | end
187 | h2 {'O FIM'}
188 | para do <<-END_PARAGRAPH
189 | Use-o para o bem e não para o mal. :-) E se você achou este tutorial útil
190 | (ou confuso, ou se você encontrou um erro),
191 | me faça saber!
192 | END_PARAGRAPH
193 | end
194 |
195 | end
196 | end
197 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/blocks_procs.rb:
--------------------------------------------------------------------------------
1 | module BlocksProcs
2 | #
3 | # BLOCKS AND PROCS
4 | #
5 |
6 | def generateBlocksProcs
7 | para do <<-END_PARAGRAPH
8 | Este é, definitivamente, um dos recursos mais legais de Ruby. Algumas
9 | outras linguagens têm esse recurso, porém elas podem chamar isso
10 | de formas diferentes (como closures), mas muitas
11 | das mais populares não, o que é uma pena.
12 | END_PARAGRAPH
13 | end
14 | para do <<-END_PARAGRAPH
15 | Então o que é essa nova coisa legal? É a habilidade de pegar
16 | um bloco de código (código entre #{code 'do'}
17 | e #{code 'end'}), amarrar tudo em um objeto (chamado de
18 | proc), armazenar isso em uma variável e passar isso
19 | para um método, e rodar o código do bloco quando você quiser
20 | (mais de uma vez, se você quiser). Então, é como se fosse um método,
21 | exceto pelo fato de que isso não está em um objeto (isso é um objeto),
22 | e você pode armazená-lo ou passá-lo adiante, como com qualquer outro objeto.
23 | Acho que é hora de um exemplo:
24 | END_PARAGRAPH
25 | end
26 | prog do <<-END_CODE
27 | saudacao = Proc.new do
28 | puts 'Olá!'
29 | end
30 |
31 | saudacao.call
32 | saudacao.call
33 | saudacao.call
34 | END_CODE
35 | end
36 | para do <<-END_PARAGRAPH
37 | Eu criei uma proc (eu acho que é abreviatura para "procedimento",
38 | mas o que importa é que rima com "block") que tem um bloco de código, então
39 | eu chamei (#{code 'call'}) a proc três vezes.
40 | Como você pode ver, parece, em muito, com um método.
41 | END_PARAGRAPH
42 | end
43 | para do <<-END_PARAGRAPH
44 | Atualmente, é muito mais parecido com um método do que eu mostrei para você,
45 | porque blocos podem receber parâmetros:
46 | END_PARAGRAPH
47 | end
48 | prog do <<-END_CODE
49 | VoceGostade = Proc.new do |umaBoaCoisa|
50 | puts 'Eu *realmente* gosto de '+umaBoaCoisa+'!'
51 | end
52 |
53 | VoceGostade.call 'chocolate'
54 | VoceGostade.call 'ruby'
55 | END_CODE
56 | end
57 | para do <<-END_PARAGRAPH
58 | Certo, então nós vimos o que blocos e procs são e como os usar, mas e daí?
59 | Por que não usar apenas métodos? Bem, isso é porque existem algumas coisas
60 | que você não pode fazer com métodos. Particularmente, você não pode passar
61 | métodos para outros métodos (mas você pode passar procs para métodos), e
62 | métodos não podem retornar outros métodos (mas podem retornar procs). É apenas
63 | por isso que procs são objetos; métodos não.
64 | END_PARAGRAPH
65 | end
66 | para do <<-END_PARAGRAPH
67 | (De qualquer forma, isso parece familiar? Sim, você já viu blocos antes... quando
68 | você aprendeu sobre iteradores. Mas vamos voltar a falar disso daqui a pouco.)
69 | END_PARAGRAPH
70 | end
71 | h2 { 'Métodos que Recebem Procs' }
72 | para do <<-END_PARAGRAPH
73 | Quando passamos uma proc em um método, nós podemos controlar como, se ou quantas vezes
74 | nós vamos chamar a proc. Por exemplo, posso dizer que há uma coisa que nós queremos
75 | fazer antes e depois que um código é executado:
76 | END_PARAGRAPH
77 | end
78 | prog do <<-END_CODE
79 | def FacaUmaCoisaImportante umaProc
80 | puts 'Todo mundo apenas ESPERE! Eu tenho uma coisa a fazer...'
81 | umaProc.call
82 | puts 'Certo pessoal, Eu terminei. Voltem a fazer o que estavam fazendo.'
83 | end
84 |
85 | digaOla = Proc.new do
86 | puts 'olá'
87 | end
88 |
89 | digaTchau = Proc.new do
90 | puts 'tchau'
91 | end
92 |
93 | FacaUmaCoisaImportante digaOla
94 | FacaUmaCoisaImportante digaTchau
95 | END_CODE
96 | end
97 | para do <<-END_PARAGRAPH
98 | Talvez isso não pareça tão fabuloso... mas é. :-)
99 | É muito comum em programação que alguns requesitos críticos sejam executados.
100 | Se você grava um arquivo, por exemplo, você deve abrir o arquivo, escrever
101 | o que quiser lá dentro e então fechar o arquivo. Se você se esquecer de fechar o arquivo,
102 | Coisas Ruins(tm) podem acontecer. Mas toda a vez que você quiser salvar ou carregar um arquivo,
103 | você deve fazer a mesma coisa: abrir o arquivo, fazer o que você realmente quiser com ele
104 | e então fechar o arquivo. Isso é entediante e fácil de esquecer. Em Ruby, salvar (ou carregar)
105 | arquivos funciona similarmente com o código anterior, então você não precisa se preocupar
106 | com nada além de o que você quer salvar (ou carregar) (No próximo capítulo eu vou lhe
107 | mostrar como fazer coisas como salvar e carregar arquivos).
108 | END_PARAGRAPH
109 | end
110 | para do <<-END_PARAGRAPH
111 | Você pode também escrever métodos que vão determinar quantas vezes, ou mesmo
112 | se uma proc será chamada. Aqui está um método que irá chamar uma proc
113 | metade do tempo, e outra que irá chamar a proc duas vezes.
114 | END_PARAGRAPH
115 | end
116 | prog do <<-END_CODE
117 | def talvezFaca umaProc
118 | if rand(2) == 0
119 | umaProc.call
120 | end
121 | end
122 |
123 | def FacaDuasVezes umaProc
124 | umaProc.call
125 | umaProc.call
126 | end
127 |
128 | piscar = Proc.new do
129 | puts ''
130 | end
131 |
132 | olhandofixamente = Proc.new do
133 | puts ''
134 | end
135 |
136 | talvezFaca piscar
137 | talvezFaca olhandofixamente
138 | FacaDuasVezes piscar
139 | FacaDuasVezes olhandofixamente
140 | END_CODE
141 | end
142 | para do <<-END_PARAGRAPH
143 | (Se você recarregar essa página algumas vezes, você verá que a saída muda)
144 | Esses são alguns dos usos mais comuns de procs, que nos possibilita fazer coisas que nós
145 | simplesmente não poderíamos fazer usando apenas métodos. Claro, você pode escrever um método
146 | que "pisque" duas vezes, mas você não pode escrever um que apenas faça qualquer coisa duas vezes!
147 | END_PARAGRAPH
148 | end
149 | para do <<-END_PARAGRAPH
150 | Antes de seguirmos adiante, vamos olhar um último exemplo. Até agora,
151 | as procs que nós usamos foram muito similares umas às outras. Agora,
152 | elas serão um pouco diferentes, assim você poderá ver como um método
153 | depende das procs que lhe são passadas. Nosso método irá receber
154 | um objeto e uma proc e irá chamar essa proc naquele objeto. Se a
155 | proc retornar falso, nós saímos; caso contrário, nós chamamos a proc
156 | com o objeto retornado. Nós vamos continuar fazendo isso até que a proc
157 | retorne falso (o que é o melhor a fazer eventualmente, ou o programá irá
158 | travar). O método irá retornar o último valor não falso retornado pela proc.
159 | END_PARAGRAPH
160 | end
161 | prog do <<-END_CODE
162 | def facaAteFalso primeiraEntrada, umaProc
163 | entrada = primeiraEntrada
164 | saida = primeiraEntrada
165 |
166 | while saida
167 | entrada = saida
168 | saida = umaProc.call entrada
169 | end
170 |
171 | entrada
172 | end
173 |
174 | construindoVetorDeQuadrados = Proc.new do |vetor|
175 | ultimoNumero = vetor.last
176 | if ultimoNumero <= 0
177 | false
178 | else
179 | vetor.pop # Jogue fora o último número...
180 | vetor.push ultimoNumero*ultimoNumero # ... e o substitua com esse quadrado...
181 | vetor.push ultimoNumero-1 # ... seguido pelo número imediatamente anterior.
182 | end
183 | end
184 |
185 | sempreFalso = Proc.new do |apenasIgnoreme|
186 | false
187 | end
188 |
189 | puts facaAteFalso([5], construindoVetorDeQuadrados).inspect
190 | puts facaAteFalso('Estou escrevendo isso às 3:00; alguém me derrube!', sempreFalso)
191 | END_CODE
192 | end
193 | para do <<-END_PARAGRAPH
194 | Certo, esse foi um exemplo estranho, eu admito. Mas isso mostra como nosso método
195 | age diferentemente quando recebe diferentes procs.
196 | END_PARAGRAPH
197 | end
198 | para do <<-END_PARAGRAPH
199 | O método #{code 'inspect'} é muito parecido com o #{code 'to_s'}, exceto
200 | pelo fato de que a string retornada tenta mostrar para você o código em ruby
201 | que está construindo o objeto que você passou. Aqui ele nos mostra todo o vetor
202 | retornado pela nossa primeira chamada a #{code 'facaAteFalso'}. Você também deve
203 | ter notado que nós nunca elevamos aquele #{code '0'} ao quadrado, no fim do vetor. Já que
204 | #{code '0'} elevado ao quadrado continua apenas #{code '0'}, nós não precisamos fazer isso.
205 | E já que #{code 'sempreFalso'} foi, você sabe, sempre #{code 'falso'},
206 | #{code 'facaAteFalso'} não fez nada na segunda vez que a chamamos; apenas retornou o que
207 | lhe foi passada.
208 | END_PARAGRAPH
209 | end
210 | h2 { 'Métodos que Retornam Procs' }
211 | para do <<-END_PARAGRAPH
212 | Uma das outras coisas legais que você pode fazer com procs é
213 | criá-las em métodos e retorná-las. Isso permite toda uma variedade
214 | de poderes de programação malucos (coisas com nomes impressionantes,
215 | como avaliação preguiçosa, estrutura de dados infinita,
216 | e temperando com curry), mas o fato é de que eu nunca faço isso
217 | na prática e eu não me lembro de ter visto ninguém fazendo isso. Eu acho
218 | que isso é o tipo de coisa que você acaba não fazendo em Ruby, ou talvez
219 | Ruby apenas encoraje-o a achar outras soluções: eu não sei. De qualquer forma,
220 | eu vou tocar no assunto apenas brevemente.
221 | END_PARAGRAPH
222 | end
223 | para do <<-END_PARAGRAPH
224 | Nesse exemplo, #{code 'compor'} recebe duas procs e retorna uma nova proc
225 | que, quando chamada, chama uma terceira proc e passa seu resultado
226 | para a segunda proc.
227 | END_PARAGRAPH
228 | end
229 | prog do <<-END_CODE
230 | def compor proc1, proc2
231 | Proc.new do |x|
232 | proc2.call(proc1.call(x))
233 | end
234 | end
235 |
236 | quadrado = Proc.new do |x|
237 | x * x
238 | end
239 |
240 | dobre = Proc.new do |x|
241 | x + x
242 | end
243 |
244 | dobreeEleve = compor dobre, quadrado
245 | eleveeDobre = compor quadrado, dobre
246 |
247 | puts dobreeEleve.call(5)
248 | puts eleveeDobre.call(5)
249 | END_CODE
250 | end
251 | para do <<-END_PARAGRAPH
252 | Note que a chamada para #{code 'proc1'} deve ser inserida
253 | entre parenteses dentro de #{code 'proc2'}, para que seja executada primeiro.
254 | END_PARAGRAPH
255 | end
256 | h2 { 'Passando Blocos (E Não Procs) para Métodos' }
257 | para do <<-END_PARAGRAPH
258 | Certo, isso foi muito interessante academicamente, mas de pouca
259 | utilidade prática. Uma porção desse problema é que há três passos
260 | que você deve seguir (definir o método, construir a proc e chamar
261 | o método com a proc), quando eles podem ser resumidos em apenas
262 | dois (definir o método e passar o bloco diretamente ao método,
263 | sem usar uma proc), uma vez que na maior parte das vezes você não
264 | vai querer usar a proc ou o bloco depois que o passar para um método.
265 | Bem, você não sabe, mas Ruby tem isso para nós! Na verdade,
266 | você já estava fazendo isso todas as vezes que usou iteradores.
267 | END_PARAGRAPH
268 | end
269 | para do <<-END_PARAGRAPH
270 | Eu vou mostrar a você um exemplo rápido, então nós vamos falar sobre isso.
271 | END_PARAGRAPH
272 | end
273 | # HACK ALERT!!! (Eu não posso chegar a um namespace global transparentemente
274 | # de dentro do objeto StringIO em um script mod_ruby.)
275 | arrayClassHack = <<-END_CODE
276 | def cadaComparacao(&eraUmBloco_agoraUmaProc)
277 | eIgual = true # Nós começamos com "verdadeiro" porque vetores começam com 0, mesmo se iguais.
278 |
279 | self.each do |objeto|
280 | if eIgual
281 | eraUmBloco_agoraUmaProc.call objeto
282 | end
283 |
284 | eIgual = (not eIgual) # Comutando entre igual para diferente, ou de diferente para igual.
285 | end
286 | end
287 | END_CODE
288 |
289 | Array.module_eval arrayClassHack # Esta é a definição real do método.
290 | # A seguir é definido um método em "outra" classe de inteiros:
291 | # FIM HACK ALERT!!!
292 | prog do <<-END_CODE
293 | class Array
294 |
295 | #{arrayClassHack}
296 | end
297 |
298 | ['maçã', 'maçã podre', 'cereja', 'mamona'].cadaComparacao do |fruta|
299 | puts 'Hum! Eu adoro tortas de '+fruta+', você não?'
300 | end
301 |
302 | # Lembre-se, nós estamos pegando os mesmos elementos numerados
303 | # do array, todos que se relacionam com os outros números,
304 | # apenas porque gosto de causar esse tipo de problema.
305 | [1, 2, 3, 4, 5].cadaComparacao do |bola_estranha|
306 | puts bola_estranha.to_s+' não é um número!'
307 | end
308 | END_CODE
309 | end
310 | para do <<-END_PARAGRAPH
311 | Para passar um bloco para #{code 'cadaComparacao'}, tudo o que temos que fazer
312 | é anexar o bloco após o método. Você pode passar um bloco para qualquer método
313 | dessa maneira, apesar de que muitos métodos vão apenas ignorar o bloco. Para
314 | fazer seu método não ignorar o bloco, mas pegá-lo e transformá-lo em
315 | uma proc, ponha o nome da proc no começo da lista dos parâmetros do seu método,
316 | precedido por um 'e' comercial (#{code '&'}). Essa parte é um pequeno truque,
317 | mas não é tão ruim, e você apenas precisa fazer isso uma vez (quando você
318 | define o método). Então você pode usar o método de novo, e de novo e de novo,
319 | assim como os métodos da linguagem que aceitam blocos, como o #{code 'each'}
320 | e o #{code 'times'} (Lembra-se do #{code '5.times do'}...?).
321 | END_PARAGRAPH
322 | end
323 | para do <<-END_PARAGRAPH
324 | Se você estiver confuso, apenas lembre-se do que supostamente o método
325 | #{code 'cadaComparacao'} faz: chama o bloco passado como parâmetro para
326 | cada elemento no vetor. Depois que você o escrever e ele estiver funcionando,
327 | você não vai precisar pensar sobre o que está acontecendo realmente por baixo
328 | dos panos ("qual bloco é chamado quando??"); na verdade, é exatamente por isso
329 | que escrevemos métodos assim: nós nunca mais vamos precisar pensar sobre
330 | como eles funcionam novamente. Nós vamos apenas usar-los.
331 | END_PARAGRAPH
332 | end
333 | para do <<-END_PARAGRAPH
334 | Eu lembro que uma vez eu quis cronometrar quanto tempo cada
335 | seção do meu código estava demorando (Isso é algo conhecido como
336 | sumarizar o código). Então, eu escrevi um método que
337 | pegava o tempo antes de executar o código, o executava e então
338 | fazia uma nova medição do tempo e me retornava a diferença. Eu
339 | não estou conseguindo achar o código agora, mas eu não preciso disso:
340 | provavelmente é um código parecido com esse:
341 | END_PARAGRAPH
342 | end
343 | prog do <<-END_CODE
344 | def sumario descricaoDoBloco, &bloco
345 | tempoInicial = Time.now
346 |
347 | bloco.call
348 |
349 | duracao = Time.now - tempoInicial
350 |
351 | puts descricaoDoBloco+': '+duracao.to_s+' segundos'
352 | end
353 |
354 | sumario 'dobrando 25000 vezes' do
355 | numero = 1
356 |
357 | 25000.times do
358 | numero = numero + numero
359 | end
360 |
361 | puts numero.to_s.length.to_s+' dígitos' # É isso mesmo: o número de dígitos nesse número ENORME.
362 | end
363 |
364 | sumario 'contando até um milhão' do
365 | numero = 0
366 |
367 | 1000000.times do
368 | numero = numero + 1
369 | end
370 | end
371 | END_CODE
372 | end
373 | para do <<-END_PARAGRAPH
374 | Que simplicidade! Que elegância! Com aquele pequeno método
375 | eu posso, agora, facilmente cronometrar qualquer seção, de qualquer
376 | programa, que eu queira, eu apenas preciso jogar o código para um bloco
377 | e enviar ele para o #{code 'sumario'}.
378 | O que poderia ser mais simples? Em muitas linguagens, eu teria que
379 | adicionar explicitamente o código de cronometragem (tudo o que está
380 | em #{code 'sumario'}) em volta de qualquer seção que eu queira medir.
381 | Em Ruby, porém, eu deixo tudo em um só lugar, e (o mais importante)
382 | fora do meu caminho!
383 | END_PARAGRAPH
384 | end
385 | h2 {'Algumas Coisinhas Para Tentar'}
386 | para do <<-END_PARAGRAPH
387 | • Relógio Cuco. Escreva um método que pegue um bloco
388 | e o chame de hora em hora. Assim, se eu passar o bloco #{code "do puts 'DONG!' end"},
389 | ele deve tocar como um relógio cuco. Teste seu método com diferentes
390 | blocos (inclusive o que eu mostrei para você).
391 | Dica: Você pode usar
392 | #{code 'Time.now.hour'} para pegar a hora atual.
393 | Porém, isso retorna um número entre #{code '0'} e #{code '23'},
394 | então você deve alterar esses números para os números de um relógio normal, entre
395 | (#{code '1'} e #{code '12'}).
396 | END_PARAGRAPH
397 | end
398 | para do <<-END_PARAGRAPH
399 | • Logger do programa. Escreva um método chamado #{code 'log'}, que
400 | pegue uma string como descrição de um bloco e, é claro, um bloco. Similarmente ao
401 | #{code 'FacaUmaCoisaImportante'}, essa deve retornar (#{code 'puts'}) uma string
402 | dizendo que o bloco foi iniciado e outra string ao fim, dizendo que é o fim da
403 | execução do bloco, e também dizendo o que o bloco retornou. Teste seu método
404 | enviando um bloco de código. Dentro do bloco, coloque outra chamada para
405 | #{code 'log'}, passando outro bloco para o mesmo (isto é chamado de nesting).
406 | Em outras palavras, sua saída deve se parecer com isso:
407 | END_PARAGRAPH
408 | end
409 | puts '' +
410 | 'Começando "bloco externo"...' + $/ +
411 | 'Começando "um bloco um pouco menor"...' + $/ +
412 | '..."um bloco um pouco menor" terminou retornando: 5' + $/ +
413 | 'Começando "um outro bloco"...' + $/ +
414 | '..."um outro bloco" terminou retornando: Eu gosto de comida tailandesa!' + $/ +
415 | '..."bloco externo" terminou retornando: false' + $/ +
416 | '
'
417 | para do <<-END_PARAGRAPH
418 | • Um Logger aperfeiçoado. A saída do último logger é muito difícil de
419 | ler, e fica muito pior a medida que você for usando. Seria muito mais fácil de ler
420 | se você identasse as linhas para os blocos internos. Para fazer isso, você vai precisar
421 | saber quão profundamente aninhado você está toda vez que for escrever algo no log. Para
422 | fazer isso, use uma variável global, uma variável que você possa ver de
423 | qualquer lugar de seu código. Para instânciar uma variável global, você deve
424 | precedê-la com um #{code '$'}, assim: #{code '$global'}, #{code '$nestingDepth'},
425 | e #{code '$bigTopPeeWee'}.
426 | Enfim, seu logger deve ter uma saída parecida com essa:
427 | END_PARAGRAPH
428 | end
429 | puts '' +
430 | 'Começando "bloco externo"...' + $/ +
431 | ' Começando "um pequeno bloco"...' + $/ +
432 | ' Começando "pequenino bloco"...' + $/ +
433 | ' ..."pequenino bloco" terminou retornando: muito amor' + $/ +
434 | ' ..."um pequeno bloco" terminou retornando: 42' + $/ +
435 | ' Começando "um outro bloco"...' + $/ +
436 | ' ..."um outro bloco" terminou retornando: Eu adoro comida indiana!' + $/ +
437 | '..."bloco externo" terminou retornando: true' + $/ +
438 | '
'
439 | para do <<-END_PARAGRAPH
440 | Bem, isso é tudo que você aprendeu com esse tutorial.
441 | Parabéns! Você aprendeu muito. Talvez você sinta
442 | como se não lembrasse de nada, ou talvez você tenha
443 | pulado algumas partes... Relaxe. Programação não é o que
444 | você sabe, e sim o que você faz. À medida que você for
445 | aprendendo onde procurar as coisas que você esquecer,
446 | você estará indo bem. Eu espero que você não ache que eu
447 | escrevi tudo isso sem ficar conferindo a cada minuto!
448 | Porque eu fiz isso. Eu também tive muita ajuda com os
449 | códigos que rodam em todos os exemplos desse tutorial.
450 | Mas onde eu estava pesquisando tudo e a quem
451 | eu estava pedindo ajuda?
452 | #{makeLink 'Deixe-me conhecê-lo...', :generateBeyond}
453 | END_PARAGRAPH
454 | end
455 | end
456 | end
457 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/conversion.rb:
--------------------------------------------------------------------------------
1 | module Conversion
2 | #
3 | # CONVERSION
4 | #
5 |
6 | def generateConversion
7 | para do <<-END_PARAGRAPH
8 | Nós vimos alguns tipos diferentes de objetos
9 | (#{makeLink 'números', :generateNumbers} e #{makeLink 'letras', :generateLetters}),
10 | e nós fizemos #{makeLink 'variáveis', :generateVariables} para apontar para elas;
11 | a coisa que queremos fazer a seguir é fazer com que todas se encaixem.
12 | END_PARAGRAPH
13 | end
14 | para do <<-END_PARAGRAPH
15 | Nós vimos que se desejássemos que um programa imprimisse #{output '25'},
16 | o código a seguir não funcionaria, porque
17 | você não pode somar números e strings:
18 | END_PARAGRAPH
19 | end
20 | prog false do <<-END_CODE
21 | var1 = 2
22 | var2 = '5'
23 |
24 | puts var1 + var2
25 | END_CODE
26 | end
27 | para do <<-END_PARAGRAPH
28 | Parte do problema é que seu computador não sabe se você está
29 | querendo #{output '7'} (#{code '2 + 5'}) ou #{output '25'}
30 | (#{code "'2' + '5'"}).
31 | END_PARAGRAPH
32 | end
33 | para do <<-END_PARAGRAPH
34 | Antes que possamos somar os dois, precisamos de alguma maneira
35 | de obter a versão em string de #{code 'var1'}, ou então de obter
36 | a versão inteira de #{code 'var2'}.
37 | END_PARAGRAPH
38 | end
39 | h2 {'Conversions'}
40 | para do <<-END_PARAGRAPH
41 | Para obter a versão string de um objeto, simplesmente escrevemos
42 | #{code '.to_s'} depois dele:
43 | END_PARAGRAPH
44 | end
45 | prog do <<-END_CODE
46 | var1 = 2
47 | var2 = '5'
48 |
49 | puts var1.to_s + var2
50 | END_CODE
51 | end
52 | para do <<-END_PARAGRAPH
53 | Similarmente, #{code 'to_i'} fornece a versão inteira de um objeto,
54 | e #{code 'to_f'} dá a versão float. Vejamos o que esses três método
55 | fazem (e não fazem) com mais detalhe:
56 | END_PARAGRAPH
57 | end
58 | prog do <<-END_CODE
59 | var1 = 2
60 | var2 = '5'
61 |
62 | puts var1.to_s + var2
63 | puts var1 + var2.to_i
64 | END_CODE
65 | end
66 | para do <<-END_PARAGRAPH
67 | Note que, mesmo depois que obtivemos a versão string de
68 | #{code 'var1'} por meio de #{code 'to_s'}, #{code 'var1'}
69 | sempre apontou para #{code '2'}, e nunca para #{code "'2'"}.
70 | A não ser que reatribuamos #{code 'var1'} explicitamente (o que
71 | requer um sinal de #{code '='}), ela vai apontar para #{code '2'}
72 | enquanto o programa estiver rodando.
73 | END_PARAGRAPH
74 | end
75 | para do <<-END_PARAGRAPH
76 | Agora vamos tentar algumas conversões mais interessantes (e alguma apenas
77 | esquisitas):
78 | END_PARAGRAPH
79 | end
80 | prog do <<-END_CODE
81 | puts '15'.to_f
82 | puts '99.999'.to_f
83 | puts '99.999'.to_i
84 | puts ''
85 | puts '5 é meu número favorito!'.to_i
86 | puts 'Quem foi que te perguntou sobre o 5?'.to_i
87 | puts 'Sua mãe.'.to_f
88 | puts ''
89 | puts 'stringuelingue'.to_s
90 | puts 3.to_i
91 | END_CODE
92 | end
93 | para do <<-END_PARAGRAPH
94 | É provável que tenha havido surpresas. A primeira é bem padrão e
95 | dá #{output '15'}.
96 | Depois disso, convertemos a string #{code "'99.999'"} para um float
97 | e para um inteiro. O float ficou como esperávamos; o inteiro, como
98 | sempre, foi arredondado para baixo.
99 | END_PARAGRAPH
100 | end
101 | para do <<-END_PARAGRAPH
102 | Em seguida temos alguns exemplos de strings... atípicas convertidas
103 | em números. #{code 'to_i'} ignora a primeira coisa que ela não entende,
104 | e o resto da string daquele ponto em diante. Então a primeira string
105 | foi convertida para #{code '5'}, mas as outras, já que começavam com
106 | letras, foram ignoradas por completo... então o computador só escolhe
107 | zero.
108 | END_PARAGRAPH
109 | end
110 | para do <<-END_PARAGRAPH
111 | Por fim, vimos que nossas duas últimas conversas não fizeram nada,
112 | exatamente como esperávamos.
113 | END_PARAGRAPH
114 | end
115 | h2 {'Uma Outra Olhadela em '+(code 'puts')}
116 | para do <<-END_PARAGRAPH
117 | Há alguma coisa estranha no nosso método favorito... Dê uma olhadinha:
118 | END_PARAGRAPH
119 | end
120 | prog do <<-END_CODE
121 | puts 20
122 | puts 20.to_s
123 | puts '20'
124 | END_CODE
125 | end
126 | para do <<-END_PARAGRAPH
127 | Por que é que essas três imprimem a mesma coisa? Tudo bem, as duas
128 | últimas deveriam mesmo, já que #{code '20.to_s'} é
129 | #{code "'20'"}. Mas e a primeira, o inteiro #{code '20'}? Falando nisso,
130 | faz algum sentido escrever o inteiro 20? Quando você escreve
131 | um 2 e depois um 0 num papel, você está escrevendo
132 | uma string, não um inteiro. O inteiro 20 é o número de dedos
133 | que eu possuo, e não um 2 seguido de um 0.
134 | END_PARAGRAPH
135 | end
136 | para do <<-END_PARAGRAPH
137 | O nosso amigo #{code 'puts'} carrega um grande segredo: antes de tentar
138 | escrever um objeto, #{code 'puts'} usa #{code 'to_s'} para obter a
139 | versão string do mesmo. Na verdade, o s em #{code 'puts'}
140 | está lá representando string; #{code 'puts'} na verdade
141 | significa put string (colocar string).
142 | END_PARAGRAPH
143 | end
144 | para do <<-END_PARAGRAPH
145 | Isso pode não parecer muito animador agora, mas há muitos,
146 | muitos tipos de objetos em Ruby (você vai até aprender
147 | a fazer o seu próprio!), e é bom saber o que vai acontecer
148 | se você tentar usar #{code 'puts'} num objeto muito estranho,
149 | como uma foto da sua avó, ou um arquivo de música ou algo assim.
150 | Mas isso vem depois...
151 | END_PARAGRAPH
152 | end
153 | para do <<-END_PARAGRAPH
154 | Até lá, nós temos mais alguns métodos para você, e eles permitem
155 | que escrevamos um bando de programas divertidos...
156 | END_PARAGRAPH
157 | end
158 | h2 {'Os Métodos '+(code 'gets')+' e '+(code 'chomp')}
159 | para do <<-END_PARAGRAPH
160 | Se #{code 'puts'} significa colocar string (N.T.: put significa
161 | "colocar"), acho que você pode adivinhar o que #{code 'gets'} quer dizer
162 | (N.T.: get, em inglês, entre várias acepções, significa pegar, obter).
163 | E assim como #{code 'puts'} sempre cospe strings, #{code 'gets'} vai apenas
164 | obter strings. E de onde ele as pega?
165 | END_PARAGRAPH
166 | end
167 | para do <<-END_PARAGRAPH
168 | De você! Tudo bem, do seu teclado. Já que seu teclado só produz strings,
169 | isso funciona muito bem. O que acontece, na verdade, é que #{code 'gets'}
170 | fica lá esperando, lendo o que você digita até que você pressione
171 | Enter. Vamos experimentar:
172 | END_PARAGRAPH
173 | end
174 | prog ['Tem um eco aqui?'] do <<-END_CODE
175 | puts gets
176 | END_CODE
177 | end
178 | para do <<-END_PARAGRAPH
179 | Claro, tudo que você digitar vai ser repetido para você. Rode
180 | algumas vezes e tente digitar coisas diferentes.
181 | END_PARAGRAPH
182 | end
183 | para do <<-END_PARAGRAPH
184 | Agora podemos fazer programas interativos! Neste, digite
185 | o seu nome para que ele lhe saude:
186 | END_PARAGRAPH
187 | end
188 | prog ['Chris'], 'Eca! Eu acabei de rodá-lo—escrevi meu nome—e aconteceu isto:' do <<-END_CODE
189 | puts 'Olá, qual é o seu nome?'
190 | name = gets
191 | puts 'Seu nome é ' + name + '? Que nome bonito!'
192 | puts 'Prazer em conhecê-lo, ' + name + '. :)'
193 | END_CODE
194 | end
195 | para do <<-END_PARAGRAPH
196 | Hmmm... parece que quando eu digitei as letras C,
197 | h, r, i, s, e pressionei
198 | Enter, #{code 'gets'} obteve todas as letras do meu nome
199 | e o Enter! Felizmente, existe um método exatamente
200 | pra esse tipo de coisa: #{code 'chomp'}. Ele retira qualquer
201 | Enter que esteja lá de bobeira no fim da sua string. Vamos
202 | testar aquele programa de novo, mas com #{code 'chomp'} para ajudar:
203 | END_PARAGRAPH
204 | end
205 | prog ['Chris'] do <<-END_CODE
206 | puts 'Olá, qual é o seu nome?'
207 | name = gets.chomp
208 | puts 'Seu nome é ' + name + '? Que nome bonito!'
209 | puts 'Prazer em conhecê-lo, ' + name + '. :)'
210 | END_CODE
211 | end
212 | para do <<-END_PARAGRAPH
213 | Muito melhor! Perceba que já que #{code 'name'} aponta para
214 | #{code 'gets.chomp'}, não temos que dizer #{code 'name.chomp'};
215 | #{code 'name'} já foi #{code 'mastiga'}do (N.T.: chomp, em Inglês
216 | é "mastigar").
217 | END_PARAGRAPH
218 | end
219 | h2 {'Umas Coisinhas Para Tentar'}
220 | para do <<-END_PARAGRAPH
221 | • Escreva um programa que peça o nome de uma pessoa, depois
222 | o sobrenome. Por fim, faça com que ele cumprimente a pessoa usando seu nome completo.
223 | END_PARAGRAPH
224 | end
225 | para do <<-END_PARAGRAPH
226 | • Escreva um programa que pergunte pelo número favorito de uma
227 | pessoa. Some um ao número, e sugira o resultado como um número favorito
228 | muito melhor (tenha tato ao fazê-lo).
229 | END_PARAGRAPH
230 | end
231 | para do <<-END_PARAGRAPH
232 | Assim que você terminar esses dois programas (e quaisquer outros que
233 | você queira tentar), aprenderemos mais #{makeLink('métodos', :generateMethods)} (e mais coisas sobre eles).
234 | END_PARAGRAPH
235 | end
236 | end
237 | end
238 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/flow_control.rb:
--------------------------------------------------------------------------------
1 | module FlowControl
2 | #
3 | # FLOW CONTROL
4 | #
5 |
6 | def generateFlowControl
7 | para do <<-END_PARAGRAPH
8 | Ahhhh, controle de fluxo. É aqui que tudo se junta. Ainda que
9 | este capítulo seja mais curto e fácil que o capítulo sobre
10 | #{makeLink 'métodos', :generateMethods}, ele vai abrir um mundo de
11 | possibilidades de programação.
12 | Após este capítulo, poderemos escrever programas realmente interativos;
13 | antes fizemos programas que dizem coisas diferentes
14 | dependendo do que você escreve, mas após este capítulo eles
15 | farão coisas diferentes, também. Todavia, temos que poder
16 | comparar objetos no nosso programa. Precisamos de...
17 | END_PARAGRAPH
18 | end
19 | h2 {'Métodos de Comparação'}
20 | para do <<-END_PARAGRAPH
21 | Vamos ser rápidos por aqui para chegar até as ramificações,
22 | que é onde as coisas legais começam a acontecer.
23 | Para ver se um objeto é maior ou menor que outro, usamos
24 | os métodos #{code '>'} e #{code '<'}, assim:
25 | END_PARAGRAPH
26 | end
27 | prog do <<-END_CODE
28 | puts 1 > 2
29 | puts 1 < 2
30 | END_CODE
31 | end
32 | para do <<-END_PARAGRAPH
33 | Tudo em ordem. Do mesmo modo, podemos descobrir se um objeto
34 | é maior-ou-igual-que (ou menor-ou-igual-que) outro com os métodos
35 | #{code '>='} e #{code '<='}.
36 | END_PARAGRAPH
37 | end
38 | prog do <<-END_CODE
39 | puts 5 >= 5
40 | puts 5 <= 4
41 | END_CODE
42 | end
43 | para do <<-END_PARAGRAPH
44 | Por fim, podemos descobrir se dois objetos são iguais
45 | ou não usando #{code '=='} (que significa "estes objetos são iguais?")
46 | e #{code '!='} (que significa "estes objetos são diferentes?").
47 | É importante não confundir #{code '='} com #{code '=='}. #{code '='}
48 | serve para dizer a uma variável que aponte para um objeto
49 | (atribuição), e #{code '=='} é para fazer a pergunta: "Estes dois
50 | objetos são iguais?".
51 | END_PARAGRAPH
52 | end
53 | prog do <<-END_CODE
54 | puts 1 == 1
55 | puts 2 != 1
56 | END_CODE
57 | end
58 | para do <<-END_PARAGRAPH
59 | E é claro que também podemos comparar strings. Quando strings
60 | são comparadas, leva-se em conta seus ordenamentos
61 | lexicográficos, que, trocando em miúdos, significa a ordem delas
62 | no dicionário. #{code 'cachorro'} vem antes de #{code 'gato'} no
63 | dicionário, então:
64 | END_PARAGRAPH
65 | end
66 | prog do <<-END_CODE
67 | puts 'cachorro' < 'gato'
68 | END_CODE
69 | end
70 | para do <<-END_PARAGRAPH
71 | Há um porém: os computadores costumam ordenar letras
72 | maiúsculas antes de minúsculas, como se viessem antes (é assim que
73 | guardam as letras em fontes, por exemplo: todas as letras
74 | maiúsculas primeiro, seguidas das minúsculas).
75 | Isso significa que o computador vai pensar que #{code "'Zoológico'"} vem
76 | antes de #{code "'abelha'"}, então se você quiser descobrir qual
77 | palavra viria primeiro num dicionário de verdade, use #{code 'downcase'}
78 | (ou #{code 'upcase'} ou #{code 'capitalize'}) em ambas as palavras
79 | antes de tentar compará-las.
80 | END_PARAGRAPH
81 | end
82 | para do <<-END_PARAGRAPH
83 | Uma última observação antes de Ramificações: os
84 | métodos de comparação não estão nos dando as strings #{code "'true'"}
85 | e #{code "'false'"}; elas estão nos dando os objetos especiais
86 | #{code 'true'} e #{code 'false'} (claro, #{code 'true.to_s'} nos dá
87 | #{code "'true'"}, que é como #{code 'puts'} imprimiu #{code "'true'"}).
88 | #{code 'true'} e #{code 'false'} são usados o tempo todo em...
89 | END_PARAGRAPH
90 | end
91 | h2 {'Ramificações (Branching)'}
92 | para do <<-END_PARAGRAPH
93 | "Ramificação" é um conceito simples, mas poderoso. Na verdade,
94 | é tão simples que aposto que nem tenho que explicá-lo; deixa
95 | eu mostrar para você:
96 | END_PARAGRAPH
97 | end
98 | executa1 = {:input => ['Chris']}
99 | executa2 = {:input => ['Chewbacca'], :remark => 'Mas se colocarmos um nome diferente...'}
100 | progN executa1, executa2 do <<-END_CODE
101 | puts 'Olá, qual é o seu nome?'
102 | nome = gets.chomp
103 | puts 'Olá, ' + nome + '.'
104 | if nome == 'Chris'
105 | puts 'Que nome bonito!'
106 | end
107 | END_CODE
108 | end
109 | para do <<-END_PARAGRAPH
110 | E isso é ramificar. Se o que vem depois de #{code 'if'} (N.T.—se) é
111 | #{code 'true'}, nós executamos o código entre #{code 'if'} e
112 | #{code 'end'}. Se o que vem depois de #{code 'if'} é #{code 'false'},
113 | não executamos nada. Claro e simples.
114 | END_PARAGRAPH
115 | end
116 | para do <<-END_PARAGRAPH
117 | Eu indentei o código entre #{code 'if'} e #{code 'end'} porque
118 | acho que fica mais fácil acompanhar as ramificações assim. Quase
119 | todos os programadores fazem isso, independente da linguagem
120 | em que estejam trabalhando. Pode não parecer muito útil neste
121 | exemplo pequeno, mas quando as coisas ficam mais complexas,
122 | faz uma baita diferença.
123 | END_PARAGRAPH
124 | end
125 | para do <<-END_PARAGRAPH
126 | Muitas vezes gostaríamos que um programa fizesse uma coisa se
127 | uma expressão for #{code 'true'}, e outra se for #{code 'false'}.
128 | É para isso que serve #{code 'else'}:
129 | END_PARAGRAPH
130 | end
131 | executa1 = {:input => ['Chris']}
132 | executa2 = {:input => ['Ringo'], :remark => 'Agora vamos tentar um nome diferente...'}
133 | progN executa1, executa2 do <<-END_CODE
134 | puts 'Eu sou um vidente. Diga-me seu nome:'
135 | nome = gets.chomp
136 | if nome == 'Chris'
137 | puts 'Vejo coisas maravilhosas no seu futuro.'
138 | else
139 | puts 'Seu futuro é... Ó, Deus! Olha a hora!'
140 | puts 'Eu tenho que ir, mil perdões!'
141 | end
142 | END_CODE
143 | end
144 | para do <<-END_PARAGRAPH
145 | Ramificar é como deparar com uma bifurcação no código: tomamos
146 | o caminho para as pessoas com o #{code "nome == 'Chris'"} ou
147 | #{code 'else'}, tomamos o outro caminho?
148 | END_PARAGRAPH
149 | end
150 | para do <<-END_PARAGRAPH
151 | E como os galhos de uma árvore, você pode ter ramificações
152 | que contêm suas próprias ramificações:
153 | END_PARAGRAPH
154 | end
155 | executa1 = {:input => ['chris', 'sim']}
156 | executa2 = {:input => ['Chris'], :remark => 'Está bem, vou capitalizar...'}
157 | progN executa1, executa2 do <<-END_CODE
158 | puts 'Olá, e bem-vindo à aula de Português.'
159 | puts 'Meu nome é professora Hélia. Seu nome é...?'
160 | nome = gets.chomp
161 |
162 | if nome == nome.capitalize
163 | puts 'Por favor, sente-se, ' + nome + '.'
164 | else
165 | puts nome + '? Você quer dizer ' + nome.capitalize + ', não é?'
166 | puts 'Você não sabe nem escrever seu nome??'
167 | resposta = gets.chomp
168 |
169 | if resposta.downcase == 'sim'
170 | puts 'Hunf! Vá, sente-se!'
171 | else
172 | puts 'FORA!!!'
173 | end
174 | end
175 | END_CODE
176 | end
177 | para do <<-END_PARAGRAPH
178 | Às vezes pode ficar confuso entender onde colocar os
179 | #{code 'if'}s, #{code 'else'}s e #{code 'end'}s. O que eu faço
180 | é escrever o #{code 'end'} ao mesmo tempo que escrevo
181 | o #{code 'if'}. Então enquanto eu estava escrevendo o programa
182 | acima, ele estava primeiro assim:
183 | END_PARAGRAPH
184 | end
185 | prog false do <<-END_CODE
186 | puts 'Olá, e bem-vindo à aula de Português.'
187 | puts 'Meu nome é professora Hélia. Seu nome é...?'
188 | nome = gets.chomp
189 |
190 | if nome == nome.capitalize
191 | else
192 | end
193 | END_CODE
194 | end
195 | para do <<-END_PARAGRAPH
196 | Aí eu preenchi com comentários, coisas no
197 | código que o computador irá ignorar:
198 | END_PARAGRAPH
199 | end
200 | prog false do <<-END_CODE
201 | puts 'Olá, e bem-vindo à aula de Português.'
202 | puts 'Meu nome é professora Hélia. Seu nome é...?'
203 | nome = gets.chomp
204 |
205 | if nome == nome.capitalize
206 | # Ela é cordial.
207 | else
208 | # Ela fica brava.
209 | end
210 | END_CODE
211 | end
212 | para do <<-END_PARAGRAPH
213 | Qualquer coisa após um #{code '#'} é considerado um comentário (a
214 | não ser, é claro, que você esteja em uma string). Depois de preencher
215 | com comentários, substituí-os por código funcional. Algumas
216 | pessoas gostam de deixá-los no arquivo; particularmente, creio
217 | que código bem-escrito fala por si. Eu costumava escrever
218 | mais comentários, mas quanto mais "fluente" fico em Ruby, menos
219 | faço uso deles. Eles me distraem boa parte do tempo. É uma escolha
220 | individual; você vai encontrar o seu estilo (normalmente em
221 | constante evolução). Então meu próximo passo ficou assim:
222 | END_PARAGRAPH
223 | end
224 | prog false do <<-END_CODE
225 | puts 'Olá, e bem-vindo à aula de Português.'
226 | puts 'Meu nome é professora Hélia. Seu nome é...?'
227 | nome = gets.chomp
228 |
229 | if nome == nome.capitalize
230 | puts 'Por favor, sente-se, ' + nome + '.'
231 | else
232 | puts nome + '? Você quer dizer ' + nome.capitalize + ', não é?'
233 | puts 'Você não sabe nem escrever seu nome??'
234 | resposta = gets.chomp
235 |
236 | if resposta.downcase == 'sim'
237 | else
238 | end
239 | end
240 | END_CODE
241 | end
242 | para do <<-END_PARAGRAPH
243 | Mais uma vez escrevi #{code 'if'}, #{code 'else'} e #{code 'end'}
244 | ao mesmo tempo. Realmente me ajuda a saber "onde estou" no código.
245 | Também faz com que o trabalho pareça mais fácil porque posso me
246 | concentrar em uma parte pequena, como preencher o código entre
247 | #{code 'if'} e #{code 'else'}. Uma outra vantagem de fazê-lo
248 | desta maneira é que o computador pode entender o programa em
249 | qualquer estágio. Qualquer uma das versões inacabadas do
250 | programa que eu lhe mostrei rodariam. Elas não estavam terminadas,
251 | mas eram programas funcionais. Desta maneira eu pude testar
252 | enquanto escrevia, o que me ajudou a ver como o programa
253 | progredia e o que precisava ser melhorado. Quando ele passou
254 | em todos os testes, eu soube que estava pronto!
255 | END_PARAGRAPH
256 | end
257 | para do <<-END_PARAGRAPH
258 | Essas dicas vão ajudá-lo a escrever programas que se ramificam,
259 | mas também ajudam com outro tipo central de controle de fluxo:
260 | END_PARAGRAPH
261 | end
262 | h2 {'Repetição (Looping)'}
263 | para do <<-END_PARAGRAPH
264 | Você vai querer com alguma freqüência que o computador faça a mesma
265 | coisa várias e várias vezes—afinal, é nisso que os computadores,
266 | em teoria, são bons.
267 | END_PARAGRAPH
268 | end
269 | para do <<-END_PARAGRAPH
270 | Quando você manda o seu computador ficar repetindo algo, você
271 | também precisa dizê-lo quando parar. Computadores nunca se entediam,
272 | então se você não mandar o seu parar, ele não parará. Garantimos
273 | que isso não aconteça ao dizermos que ele deve repetir certas partes
274 | de um programa #{code 'while'} (N.T.—enquanto) uma condição
275 | especificada for verdadeira. O funcionamento é bem parecido com o do
276 | #{code 'if'}:
277 | END_PARAGRAPH
278 | end
279 | prog ['Olá?', 'Oi!', 'Muito prazer em conhecê-lo.', 'Ah... que amor!', 'tchau'] do <<-END_CODE
280 | comando = ''
281 |
282 | while comando != 'tchau'
283 | puts comando
284 | comando = gets.chomp
285 | end
286 |
287 | puts 'Volte logo!'
288 | END_CODE
289 | end
290 | para do <<-END_PARAGRAPH
291 | E isso é um loop (você deve ter notado a linha em branco no começo
292 | da saída; ela vem do primeiro #{code 'puts'}, antes do primeiro
293 | #{code 'gets'}. Como você modificaria o programa para se livrar
294 | dessa primeira linha? Teste! Funcionou exatamente como o
295 | programa acima, fora aquela primeira linha em branco?).
296 | END_PARAGRAPH
297 | end
298 | para do <<-END_PARAGRAPH
299 | Loops, ou repetições, permitem que você faça várias coisas
300 | interessantes, como sei que você pode imaginar. Mas também
301 | podem causar problemas se você cometer algum erro. E se o computador
302 | ficar preso num loop infinito? Se você acha que isso pode ter acontecido,
303 | é só segurar a tecla Ctrl e pressionar C.
304 | END_PARAGRAPH
305 | end
306 | para do <<-END_PARAGRAPH
307 | Antes de começarmos a brincar com loops, vamos aprender algumas
308 | coisinhas para facilitar nossa vida.
309 | END_PARAGRAPH
310 | end
311 | h2 {'Um Pouco de Lógica'}
312 | para do <<-END_PARAGRAPH
313 | Vamos dar uma olhada no nosso primeiro programa com ramificações. E
314 | se minha esposa chegasse em casa, visse o programa, tentasse usá-lo
315 | e ele não dissesse que nome bonito ela tem? Eu não
316 | gostaria de magoá-la (ou de dormir no sofá), então vamos reescrevê-lo:
317 | END_PARAGRAPH
318 | end
319 | prog ['Katy'] do <<-END_CODE
320 | puts 'Olá, qual é o seu nome?'
321 | nome = gets.chomp
322 | puts 'Olá, ' + nome + '.'
323 | if nome == 'Chris'
324 | puts 'Que nome bonito!'
325 | else
326 | if nome == 'Katy'
327 | puts 'Que nome bonito!'
328 | end
329 | end
330 | END_CODE
331 | end
332 | para do <<-END_PARAGRAPH
333 | Bom, funciona... mas não é lá um programa muito bonito. E por quê?
334 | A melhor regra que eu aprendi sobre programação foi a regra
335 | DRY: Don't Repeat Yourself
336 | (N.T.—Não Se Repita). Eu poderia escrever um livro só sobre
337 | o quão boa ela é. No nosso caso, repetimos a linha
338 | #{code 'Que nome bonito!'}. Por que é que isso é um problema? Bem,
339 | e se eu cometi um erro de digitação quando eu reescrevi? E se eu
340 | quisesse mudar de #{code 'bonito'} para #{'gracioso'} em ambas
341 | as linhas? Eu sou preguiçoso, lembra? Basicamente, se eu quero
342 | que meu programa faça a mesma coisa quando receber #{code 'Chris'} ou
343 | #{code 'Katy'}, então ele realmente deve fazer a mesma coisa:
344 | END_PARAGRAPH
345 | end
346 | prog ['Katy'] do <<-END_CODE
347 | puts 'Olá, qual é o seu nome?'
348 | nome = gets.chomp
349 | puts 'Olá, ' + nome + '.'
350 | if (nome == 'Chris' or nome == 'Katy')
351 | puts 'Que nome bonito!'
352 | end
353 | END_CODE
354 | end
355 | para do <<-END_PARAGRAPH
356 | Muito melhor. Para que funcionasse, usei #{code 'or'}. Os outros
357 | operadores lógicos são #{code 'and'} e #{code 'not'}. É
358 | sempre bom usar parênteses ao trabalhar com eles. Vamos ver como
359 | funcionam:
360 | END_PARAGRAPH
361 | end
362 | prog do <<-END_CODE
363 | euSouChris = true
364 | euSouRoxo = false
365 | euAmoComida = true
366 | euComoPedras = false
367 |
368 | puts (euSouChris and euAmoComida)
369 | puts (euAmoComida and euComoPedras)
370 | puts (euSouRoxo and euAmoComida)
371 | puts (euSouRoxo and euComoPedras)
372 | puts
373 | puts (euSouChris or euAmoComida)
374 | puts (euAmoComida or euComoPedras)
375 | puts (euSouRoxo or euAmoComida)
376 | puts (euSouRoxo or euComoPedras)
377 | puts
378 | puts (not euSouRoxo)
379 | puts (not euSouChris)
380 | END_CODE
381 | end
382 | para do <<-END_PARAGRAPH
383 | O único deles que pode enganá-lo é #{code 'or'} (N.T.—ou).
384 | Em português, usa-se "ou" para dizer "um ou outro, mas não os dois".
385 | Por exemplo, sua mãe pode lhe dizer: "Para sobremesa você pode escolher
386 | torta ou bolo". Ela não deu a opção de escolher os dois!
387 | Um computador, por outro lado, entende #{code 'or'} como "ou um ou outro,
388 | ou os dois" (outro jeito de colocar é "ao menos um destes é verdadeiro").
389 | É por isso que computadores são mais legais que mães.
390 | END_PARAGRAPH
391 | end
392 | h2 {'Umas Coisinhas Para Tentar'}
393 | para do <<-END_PARAGRAPH
394 | • "Um elefante incomoda muita gente..." Escreva um
395 | programa que imprima a letra para o clássico das viagens de
396 | carro, com um limite de 100 elefantes.
397 | END_PARAGRAPH
398 | end
399 | para do <<-END_PARAGRAPH
400 | • Escreva um programa Velha Surda. O que quer que
401 | você diga à velha (o que quer que você digite), ela tem
402 | que responder com #{output 'QUE?! FALA MAIS ALTO!'}, a não
403 | ser que você grite (digite tudo em maiúsculas). Se você
404 | gritar, ela pode lhe ouvir (ou ao menos pensa que pode), e
405 | sempre responde #{output 'NÃO, NÃO DESDE 1938!'} Para fazer seu
406 | programa ser realmente verossímil, faça a velha gritar
407 | um número diferente a cada vez; talvez qualquer ano aleatório
408 | entre 1930 e 1950 (a última parte é opcional, e ficaria muito
409 | mais fácil se você lesse a seção sobre o gerador de números
410 | randômicos do Ruby no capítulo sobre
411 | #{makeLink 'métodos', :generateMethods}). Você não pode parar
412 | de falar com a velha enquanto não gritar #{input 'TCHAU'}.
413 | Dica: Não esqueça do #{code 'chomp'}
414 | ! #{code "'TCHAU'"} com um enter não é a mesma coisa que
415 | #{code "'TCHAU'"} sem!
416 | Dica 2: Tente pensar em que partes do programa
417 | as coisas acontecem repetidamente. Todas elas devem estar no seu
418 | loop #{code 'while'}.
419 | END_PARAGRAPH
420 | end
421 | para do <<-END_PARAGRAPH
422 | • Melhore o seu programa Velha Surda: e se a velha
423 | não quiser que você vá embora? Quando você gritar #{input 'TCHAU'},
424 | ela pode fingir que não lhe ouve. Mude seu programa anterior
425 | para que você tenha que gritar #{input 'TCHAU'} três vezes em
426 | seqüência. Teste bem o seu programa: se você gritar
427 | #{input 'TCHAU'} três vezes, mas não em seqüência, você tem
428 | que continuar falando com a velha.
429 | END_PARAGRAPH
430 | end
431 | para do <<-END_PARAGRAPH
432 | • Anos bissextos. Escreva um programa que pergunte um
433 | ano inicial e um ano final, e imprima com #{code 'puts'} todos
434 | os anos bissextos entre eles (e os incluindo, se eles também
435 | forem bissextos). Anos bissextos são sempre divisíveis por
436 | quatro (como 1984 e 2004). Contudo, anos divisíveis por 100
437 | não são bissextos (como 1800 e 1900)
438 | a não ser que sejam divisíveis por
439 | 400 (como 1600 e 2000, que foram de fato anos bissextos).
440 | (Sim, é bem confuso, mas não tão confuso como ter dezembro
441 | no meio do inverno, que é o que aconteceria no fim).
442 | END_PARAGRAPH
443 | end
444 | para do <<-END_PARAGRAPH
445 | Quando você terminá-las, descanse um pouco! Você já aprendeu
446 | muitas coisas. Parabéns. Você está surpreso com a quantidade
447 | de coisas que se pode mandar o computador fazer? Mais alguns capítulos
448 | e você vai poder programar praticamente tudo. Sério mesmo!
449 | Veja só tudo que você pode fazer que não podia antes de aprender
450 | sobre loops e ramificações.
451 | END_PARAGRAPH
452 | end
453 | para do <<-END_PARAGRAPH
454 | Agora vamos aprender sobre um novo tipo de objeto, que
455 | controla listas de outros objetos:
456 | #{makeLink 'arrays', :generateArrays}.
457 | END_PARAGRAPH
458 | end
459 | end
460 | end
461 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/formatting_page.rb:
--------------------------------------------------------------------------------
1 | module FormattingPage
2 | #
3 | # PÁGINA DE TESTE PARA FORMATAÇÃO
4 | #
5 |
6 | def generateFormattingPage
7 | h1 { 'Cabeçalho 1' }
8 | h2 { 'Cabeçalho 2' }
9 | h3 { 'Cabeçalho 3' }
10 | h4 { 'Cabeçalho 4' }
11 |
12 | para {'Aqui está um código com uma saída falsa:'}
13 | prog [], '...brincadeirinha, cara...', 'FANTÁSTICO!' do <<-'END_CODE'
14 | # Aqui está um código 'Ruby'.
15 | # 5 é melhor do que 6.
16 | # def wilma do end if not in, cara.
17 | #'
18 |
19 | '#Isto não deveria causar nenhum problema.'
20 | 'Nem # deveria isto\\'
21 | 'do end if elsif else case when then while def class'
22 | 'or and not next in'
23 | 'to 3 or not to 3, that is 3.7'
24 | '' + 'x'+''+''+'..'
25 | '' +'o'
26 |
27 | 8
28 | 0.09
29 | 9.9
30 | 5.times {}
31 |
32 | puts 'Eu adoro queijo.' # yo 'g'
33 | puts 5.02 + 8 + 0.002 # s'up, muva
34 |
35 | jimmy = ['yoyoyo', 66]
36 | jimmy.each do |item|
37 | puts item.inspect
38 | end
39 |
40 | puts case 'abobora'
41 | when String then 'sim'
42 | when Fixnum then 'nao'
43 | else 'talvez'
44 | end
45 |
46 | def yummy
47 | if (4 <= 5)
48 | 'Uhmmm!'
49 | elsif (4 == 5)
50 | 'Ãh?'
51 | else
52 | while (1 == 2)
53 | puts 'O quê?'
54 | end
55 | end
56 | end
57 |
58 | class ApenasAlgumaClasse
59 | def initialize
60 | @var = 5
61 | end
62 | end
63 |
64 | puts Math::PI # Deveria funcionar.
65 | puts PI # Não deveria funcionar.
66 | END_CODE
67 | end
68 | para {'Aqui está um código com entrada e saída:'}
69 | prog ['"Chris"', '&26', ''] do <<-END_CODE
70 | puts 'yoyo...wuddup?'
71 | puts 'NOME:'
72 | name = gets.chomp
73 | puts 'IDADE:'
74 | age = gets.chomp
75 | puts 'COR FAVORITA'
76 | color = gets.chomp
77 | puts 'Olá, '+name+', amante da cor '+color+' de '+age+' anos de idade. '
78 | END_CODE
79 | end
80 |
81 | para do <<-END_PARAGRAPH
82 | Olá. Eu adoro #{input 'colocar VÁRIAS coisas'}. Eu também fico animado
83 | de #{code 'codificar várias coisas'}. Existe uma tal emoção em
84 | ver tudo da excitante #{output 'saída que você pode obter'} de um
85 | programa bem escrito.
86 | END_PARAGRAPH
87 | end
88 | end
89 | end
90 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/learn_to_program.rb:
--------------------------------------------------------------------------------
1 | module LearnToProgram
2 |
3 | def initialize (cgi)
4 | @cgi = cgi
5 | @depth = 0
6 | @page = []
7 |
8 | # 'format' é uma página escondida para testar a formatação.
9 | @chapters = {'format'=>['Página de Formatação', :generateFormattingPage]}
10 | @chapters['00' ] = ['Iniciando', :generateSetup]
11 | @chapters['01' ] = ['Números', :generateNumbers]
12 | @chapters['02' ] = ['Letras', :generateLetters]
13 | @chapters['03' ] = ['Variáveis e Atribuições', :generateVariables]
14 | @chapters['04' ] = ['Misturando tudo', :generateConversion]
15 | @chapters['05' ] = ['Mais Sobre Métodos', :generateMethods]
16 | @chapters['06' ] = ['Controle de Fluxo', :generateFlowControl]
17 | @chapters['07' ] = ['Arrays e Iteradores', :generateArrays]
18 | @chapters['08' ] = ['Escrevendo seus Próprios Métodos', :generateDefMethod]
19 | @chapters['09' ] = ['Classes', :generateClasses]
20 | @chapters['10' ] = ['Blocos e Procs', :generateBlocksProcs]
21 | @chapters['11' ] = ['Além deste Tutorial', :generateBeyond]
22 | end
23 |
24 | def getChapter (method)
25 | @chapters.each do |num, chapter|
26 | return num if (method == chapter[1])
27 | end
28 | 'Main'
29 | end
30 |
31 | def selfLink (chap = nil)
32 | # REQUEST_URI includes "?Chapter=Foo"
33 | LINKADDR+'index.rb?Chapter='+(chap ? getChapter(chap) : '')
34 | end
35 |
36 | def makeLink (name, methodName)
37 | ''+name+''
38 | end
39 |
40 | def out
41 | @cgi.out { @page.join("\n")+"\n" }
42 | end
43 |
44 | def puts (string, escapeThis=false)
45 | if escapeThis
46 | string = CGI::escapeHTML string
47 | end
48 | @page << ' '*@depth+string
49 | end
50 |
51 | def escapeOutputNotInput (output)
52 | md = /#{INPUT}.*?#{INPUT.reverse}/.match output
53 | if md
54 | CGI::escapeHTML(md.pre_match) +
55 | CGI::escapeHTML(md[0]).sub(/#{INPUT}/,'').sub(/#{INPUT.reverse}/,'') +
56 | escapeOutputNotInput(md.post_match)
57 | else
58 | CGI::escapeHTML output
59 | end
60 | end
61 |
62 | def syntaxColor (str) # str provavelmente possui html-escaped.
63 | lines = str.split /\n/
64 | # L2Pcomment
65 | # L2Pstring
66 | # L2Pnumber
67 | # L2Pkeyword
68 | # L2Pdefinition
69 |
70 | lines.collect! do |line|
71 | #line += ' ' # para dividir... Precisamos disso?
72 | md = /'|#/.match line
73 | if md # Comment or string.
74 | syntaxColor(md.pre_match) +
75 | if (md[0] == '#')
76 | ''
77 | else # Big string time...
78 | md2 = /(.*?)(^|[^\\])((\\\\)*)'/.match md.post_match
79 | if (md2)
80 | md[0] + '' + $1 + $2 + $3 +
81 | '' + "'" + syntaxColor(md2.post_match)
82 | else
83 | md[0]
84 | end
85 | end
86 | else # sem comentários nem string.
87 | keywords = %w[__FILE__ and end in or self unless __LINE__
88 | begin ensure redo super until BEGIN break do
89 | false next rescue then when END case else for
90 | nil retry true while alias elsif if not
91 | return undef yield]
92 |
93 | keywords.each do |keyword|
94 | line.gsub!(/(\W|^)(#{keyword})(\W|$)/) do
95 | $1+''+$2+''+$3
96 | end
97 | end
98 |
99 | ['def', 'class', 'module'].each do |keyword|
100 | line.gsub!(/(\W|^)(#{keyword}) +([\w?]+)/) do
101 | $1+'' +$2+''+
102 | ' '+$3+''
103 | end
104 | end
105 |
106 | line.gsub!(/(^|[-{\[( ^+%*\/?;])(\d+(\.\d+)?|\.\d+)/) do
107 | $1+''+$2+''
108 | end
109 |
110 | line
111 | end
112 | end
113 |
114 | lines.join "\n"
115 | end
116 |
117 |
118 | def input (str)
119 | str = CGI::escapeHTML str
120 | str.gsub!(/ /, ' ')
121 | ''+str+''
122 | end
123 |
124 | def code (str)
125 | str = CGI::escapeHTML str
126 | str.gsub!(/ /, ' ')
127 | str = syntaxColor str
128 | ''+str+''
129 | end
130 |
131 | def output (str)
132 | str = CGI::escapeHTML str
133 | str.gsub!(/ /, ' ')
134 | ''+str+''
135 | end
136 |
137 | # Essa é a parte legal...
138 | def executeCode (code, input)
139 | # Encapsula o código para pegar erros e não ocorrer SystemExit.
140 | code = <<-END_CODE
141 | begin
142 | #{code}
143 | rescue SystemExit
144 | rescue Exception => error
145 | puts error.inspect
146 | end
147 | END_CODE
148 |
149 | strIO = StringIO.new
150 |
151 | if !input.empty?
152 | input = input.join("\n")+"\n"
153 | input = StringIO.new(input, "r")
154 | class << strIO; self; end.module_eval do
155 | ['gets', 'getc', 'read'].each do |meth|
156 | define_method(meth) do |*params|
157 | inStr = input.method(meth).call(*params)
158 | puts INPUT+inStr.chomp+(INPUT.reverse) # Echo input.
159 | inStr
160 | end
161 | end
162 | end
163 | end
164 |
165 | # Passa esses métodos para strIO:
166 | kernelMethods = ['puts', 'putc', 'gets']
167 |
168 | # Métodos de Swap out Kernel...
169 | kernelMethods.each do |meth|
170 | Kernel.module_eval "alias __temp__tutorial__#{meth}__ #{meth}"
171 | Kernel.module_eval do
172 | define_method(meth) do |*params|
173 | strIO.method(meth).call(*params)
174 | end
175 | end
176 | end
177 |
178 | begin
179 | strIO.instance_eval code
180 | rescue Exception => error # Captura erros durante o parse.
181 | return error.inspect
182 | end
183 |
184 | # ...e faz o swap de volta.
185 | kernelMethods.each do |meth|
186 | Kernel.module_eval "alias #{meth} __temp__tutorial__#{meth}__"
187 | end
188 |
189 | strIO.string
190 | end
191 |
192 |
193 | # Tags (ou similar)
194 |
195 | def para (attributes = {}, &block)
196 | method_missing(:p, attributes, &block)
197 | end
198 |
199 | def prog (execute = [], remark = nil, fakeOutput = nil, &block)
200 | if !execute
201 | return progN(&block)
202 | end
203 |
204 | run = {:input => execute}
205 | run[:remark ] = remark if remark
206 | run[:fakeOutput] = fakeOutput if fakeOutput
207 | progN(run, &block)
208 | end
209 |
210 | def progN (*trialRuns)
211 | code = yield
212 |
213 | # Retirando espaços em branco.
214 | lines = code.split $/
215 | numSpaces = lines[0].length - lines[0].sub(/ */, '').length
216 | lines.each do |line|
217 | line.sub!(/ {0,#{numSpaces}}/, '')
218 | end
219 | code = lines.join($/)
220 |
221 | prettyCode = syntaxColor(CGI::escapeHTML(code))
222 |
223 | # Spit it out.
224 | puts ''+prettyCode+'
'
225 |
226 | trialRuns.each do |run|
227 | if run[:fakeOutput]
228 | puts ''+CGI::escapeHTML(run[:fakeOutput])+'
'
229 | end
230 | if run[:remark]
231 | puts ''+run[:remark]+'
'
232 | end
233 | output = escapeOutputNotInput(executeCode(code,run[:input]))
234 | puts ''+$/+output+'
'
235 | end
236 | nil
237 | end
238 |
239 | # Cria uma tag.
240 | def method_missing (methodSymbol, attributes = {})
241 | methodName = methodSymbol.to_s
242 |
243 | attribString = ''
244 | attributes.each do |key, val|
245 | raise methodName if (key.nil? || val.nil?)
246 | attribString += ' '+key.to_s+'="'+val+'"'
247 | end
248 | if (!block_given?)
249 | puts '<'+methodName+attribString+' />'
250 | else
251 | puts '<'+methodName+attribString+'>'
252 | @depth += 1
253 | blockReturn = yield
254 | puts blockReturn if (blockReturn.kind_of?(String))
255 | @depth -= 1
256 | puts ''+methodName+'>'
257 | end
258 | nil
259 | end
260 |
261 | def self.included(base)
262 | base.extend(LearnToProgram::ClassMethods)
263 | end
264 |
265 | module ClassMethods
266 | def handle_request cgi
267 | begin
268 | if cgi.params['ShowTutorialCode'][0]
269 | tutorialSource = File.read __FILE__
270 | cgi.out('text/plain') { tutorialSource }
271 | else
272 | page = self.new cgi
273 | page.generate
274 | page.out
275 | end
276 | rescue Exception => e
277 | error_msg = <<-END_ERROR
278 | ERRO
279 | ERRO: envie um e-mail para o Chris ou para a Katy com o seguinte endereço
280 | #{e.class}: #{CGI::escapeHTML(e.message)}
281 | #{e.backtrace.join("\n")}
282 |
283 |
284 | END_ERROR
285 | cgi.out { error_msg }
286 | end
287 | end
288 | end
289 | end
290 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/letters.rb:
--------------------------------------------------------------------------------
1 | module Letters
2 | #
3 | # LETTERS
4 | #
5 |
6 | def generateLetters
7 | para do <<-END_PARAGRAPH
8 | Então, nós já aprendemos tudo sobre #{makeLink('números', :generateNumbers)},
9 | mas e as letras? Palavras? Textos?
10 | END_PARAGRAPH
11 | end
12 | para do <<-END_PARAGRAPH
13 | Nós nos referimos a grupos de letras em um programa como strings (Você
14 | pode pensar em letras impressas juntas ao longo de um banner).
15 | Para ficar mais fácil de entender quais partes do código são strings,
16 | Eu vou colorir as strings em #{STRING_COLOR}.
17 | Aqui tem alguns exemplos de strings:
18 | END_PARAGRAPH
19 | end
20 | prog false do <<-END_CODE
21 | 'Olá.'
22 | 'Ruby rocks.'
23 | '5 é meu número favorito... qual é o seu?'
24 | 'Snoopy diz #%^?&*@! quando alguém pisa no seu pé.'
25 | ' '
26 | ''
27 | END_CODE
28 | end
29 | para do <<-END_PARAGRAPH
30 | Como você pode ver, strings podem ter pontuação, dígitos, símbolos
31 | e espaços... muito mais do que apenas letras. A última string
32 | não tem nada: nós a chamamos de string vazia.
33 | END_PARAGRAPH
34 | end
35 | para do <<-END_PARAGRAPH
36 | Nós estávamos usando #{code 'puts'} para imprimir os números;
37 | vamos tentar ele de novo com algumas strings:
38 | END_PARAGRAPH
39 | end
40 | prog do <<-END_CODE
41 | puts 'Olá, mundo!'
42 | puts ''
43 | puts 'Até logo.'
44 | END_CODE
45 | end
46 | para do <<-END_PARAGRAPH
47 | Isso funcionou bem. Agora, tente umas strings você mesmo.
48 | END_PARAGRAPH
49 | end
50 | h2 {'Aritimética das String'}
51 | para do <<-END_PARAGRAPH
52 | Assim como você pode fazer aritimética com números, você também
53 | pode fazer aritimética com strings! Bem, uma parte dela... você pode
54 | adicionar strings, de qualquer forma.
55 | Vamos tentar adicionar duas strings e ver o que o #{code 'puts'}
56 | faz.
57 | END_PARAGRAPH
58 | end
59 | prog do <<-END_CODE
60 | puts 'Eu gosto de' + 'torta de maçã.'
61 | END_CODE
62 | end
63 | para do <<-END_PARAGRAPH
64 | Ops! Eu esqueci de adicionar um espaço entre #{code "'Eu gosto de'"} e #{code "'torta de maçã.'"}.
65 | Espaços não fazem importância normalmente, mas eles fazem sentido dentro de strings.
66 | (É verdade o que dizem: computadores não fazem o que você quer que eles façam,
67 | apenas o que você manda eles fazerem). Vamos tentar de novo:
68 | END_PARAGRAPH
69 | end
70 | prog do <<-END_CODE
71 | puts 'Eu gosto de ' + 'torta de maçã.'
72 | puts 'Eu gosto de' + ' torta de maçã.'
73 | END_CODE
74 | end
75 | para do <<-END_PARAGRAPH
76 | (Como você pode ver, não importa em qual string eu adicione o espaço.)
77 | END_PARAGRAPH
78 | end
79 | para do <<-END_PARAGRAPH
80 | Então você pode somar strings. Mas você pode, também, multiplicá-las!
81 | (Por um número, de qualquer forma). Veja isso:
82 | END_PARAGRAPH
83 | end
84 | prog [], '(Estou brincando... ele na verdade faz isso:)', 'piscando os olhos dela' do <<-END_CODE
85 | puts 'piscar ' * 4
86 | END_CODE
87 | end
88 | para do <<-END_PARAGRAPH
89 | Se você parar para pensar, isso realmente faz sentido. Afinal,
90 | #{code '7*3'} realmente quer dizer #{code '7+7+7'}, então #{code "'moo'*3"}
91 | apenas significa #{code "'moo'+'moo'+'moo'"}.
92 | END_PARAGRAPH
93 | end
94 | h2 {"#{code '12'} vs #{code "'12'"}"}
95 | para do <<-END_PARAGRAPH
96 | Antes de irmos mais longe, nós devemos ter certeza de que entendemos
97 | a diferença entre números e dígitos.
98 | #{code '12'} é um número, mas #{code "'12'"} é uma string de dois dígitos.
99 | END_PARAGRAPH
100 | end
101 | para do <<-END_PARAGRAPH
102 | Vamos brincar com isso um pouco:
103 | END_PARAGRAPH
104 | end
105 | prog do <<-END_CODE
106 | puts 12 + 12
107 | puts '12' + '12'
108 | puts '12 + 12'
109 | END_CODE
110 | end
111 | para do <<-END_PARAGRAPH
112 | Que tal isso?
113 | END_PARAGRAPH
114 | end
115 | prog do <<-END_CODE
116 | puts 2 * 5
117 | puts '2' * 5
118 | puts '2 * 5'
119 | END_CODE
120 | end
121 | para do <<-END_PARAGRAPH
122 | Esses exemplos foram muito diretos. De qualquer forma, se você não for
123 | muito cauteloso quando misturar strings e números, você pode cair em...
124 | END_PARAGRAPH
125 | end
126 | h2 {'Problemas'}
127 | para do <<-END_PARAGRAPH
128 | Nesse ponto, você já deve ter tentado algumas coisas que
129 | não funcionaram. Se não, aqui tem algumas:
130 | END_PARAGRAPH
131 | end
132 | prog do <<-END_CODE
133 | puts '12' + 12
134 | puts '2' * '5'
135 | END_CODE
136 | end
137 | para do <<-END_PARAGRAPH
138 | Hmmm... Uma mensagem de erro. O problema é que você
139 | não pode, realmente, adicionar um número a uma string, ou
140 | multiplicar uma string por outra string. Isso não faz muito sentido como isso:
141 | END_PARAGRAPH
142 | end
143 | prog false do <<-END_CODE
144 | puts 'Betty' + 12
145 | puts 'Fred' * 'John'
146 | END_CODE
147 | end
148 | para do <<-END_PARAGRAPH
149 | Uma coisa que você deve saber: você pode escrever #{code "'porco'*5"} em um programa,
150 | já que isso apenas quer dizer #{code '5'} conjuntos da string #{code "'porco'"}, todas adicionadas
151 | entre si. Entretanto,
152 | você não pode escrever #{code "5*'porco'"}, já que isso significa #{code "'porco'"}
153 | conjuntos do número #{code '5'}, o que é um pouco insano.
154 | END_PARAGRAPH
155 | end
156 | para do <<-END_PARAGRAPH
157 | Finalmente, e que tal um programa que imprima
158 | #{output 'Isso é um apóstrofo: \''}? Nós podemos tentar isso:
159 | END_PARAGRAPH
160 | end
161 | prog false do <<-END_CODE
162 | puts 'Isso é um apóstrofo: ''
163 | END_CODE
164 | end
165 | para do <<-END_PARAGRAPH
166 | Bem, aquilo não vai funcionar; Eu nem vou tentar executar aquilo.
167 | O computador me disse que nós terminamos com uma string.
168 | (É por isso que é bom ter um editor de texto que tenha
169 | realçador de sintaxe para você). Então, como podemos
170 | fazer com que o computador saiba que nós queremos continuar dentro da string?
171 | Nós temos que escapar o apóstrofo, assim:
172 | END_PARAGRAPH
173 | end
174 | prog do <<-END_CODE
175 | puts 'Isso é um apóstrofo: \\''
176 | END_CODE
177 | end
178 | para do <<-END_PARAGRAPH
179 | A barra invertida é um caractere de escape. Em outras palavras, se você tem
180 | uma barra invertida seguida de um caractere, isso pode ser, algumas vezes, traduzido
181 | em um novo caractere. As únicas coisas que uma barra invertida escapa, porém,
182 | são o apóstrofo e a própria barra invertida (Se você pensar a respeito,
183 | caracteres de escape devem sempre escapar a si mesmos).
184 | Acho que uns exemplos são bons agora:
185 | END_PARAGRAPH
186 | end
187 | prog do <<-END_CODE
188 | puts 'Isso é um apóstrofo: \\''
189 | puts 'uma barra invertida no fim da string: \\\\'
190 | puts 'acima\\\\embaixo'
191 | puts 'acima\\embaixo'
192 | END_CODE
193 | end
194 | para do <<-END_PARAGRAPH
195 | Uma vez que a barra invertida não escapaescapa a si mesma, as últimas duas strings são
197 | idênticas. Elas não se parecem no código, mas no seu computador
198 | elas são as mesmas.
199 | END_PARAGRAPH
200 | end
201 | para do <<-END_PARAGRAPH
202 | Se você tiver outra dúvida, apenas
203 | #{makeLink('continue lendo', :generateVariables)}! Eu não posso
204 | responder a todas as questões nesta página.
205 | END_PARAGRAPH
206 | end
207 | end
208 | end
209 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/main.rb:
--------------------------------------------------------------------------------
1 | module Main
2 | #
3 | # MAIN PAGE GENERATION
4 | #
5 |
6 | def generate
7 | srand
8 | chapNum = @cgi.params['Chapter'][0]
9 | chapter = @chapters[chapNum]
10 | chapTitle = 'Aprenda a Programar, por Chris Pine'
11 | if chapter
12 | chapTitle = chapNum + '. ' if chapNum < 'A'
13 | chapTitle.sub! /^0/, ''
14 | chapTitle += chapter[0]
15 | end
16 |
17 | puts ''
18 | html(:lang=>'pt_br') do
19 | head do
20 | meta('http-equiv'=>"Content-Type", :content=>"text/html; charset=utf-8")
21 |
22 | link(:href=>LINKADDR+'stylesheets/pine.css', :rel=>'Stylesheet', :type=>'text/css', :media=>'screen')
23 | link(:href=>LINKADDR+'stylesheets/tutorial.css', :rel=>'Stylesheet', :type=>'text/css', :media=>'screen, print')
24 | link(:href=>LINKADDR+'stylesheets/print.css', :rel=>'Stylesheet', :type=>'text/css', :media=>'print')
25 | title { chapTitle }
26 | script(:language=>'JavaScript', :src=>'http://www.gvisit.com/record.php?sid=6941c11eba5c874197e2096f9c854106', :type=>'text/javascript') {}
27 | end # head
28 | body do
29 | div(:id=>'pageWidth') do
30 | div(:id=>'headerBar') do
31 | div(:id=>'titlePicContainer') do
32 | puts ''
33 | img(:id=>'titlePic', :width=>'500', :height=>'108', :src=>'images/titleLTP_pt_br.gif', :alt=>'Aprenda a Programar')
34 | puts ''
35 | end
36 | puts ''
37 | puts '
'
39 | puts ''
40 | end
41 | div(:id=>'menuPane') do
42 | img(:id=>'menuSpearTop', :width=>'35', :height=>'38', :src=>'images/spearup_sm.gif')
43 |
44 | menuBookLink
45 |
46 | img(:width=>'64', :height=>'21', :style=>'padding: 30px;', :src=>'images/swirly.gif')
47 |
48 | menuTOC
49 |
50 | img(:id=>'menuSpearBottom', :width=>'36', :height=>'40', :src=>'images/speardown_sm.gif')
51 | end
52 | div(:id=>'contentPane') do
53 | if chapter
54 | if chapter[0]
55 | h1 {chapTitle}
56 | puts HLINE
57 | end
58 | method(chapter[1]).call
59 | else # TOC
60 | h2 { "Notas sobre a tradução em Português Brasileiro"}
61 | para do <<-END_PARAGRAPH
62 | Todo comunidade de programação é formada pelos amantes de computação, que aprendem linguagens
63 | novas no café-da-manhã, mas também uma uma grande parcela de pessoas que foram empolgadas por
64 | nós mas acabam esbarrando na barreira inicial do aprendizado. Felizmente autores como Chris
65 | Pine resolveram atacar este desafio e o resultado que temos é uma excelente material para
66 | programadores iniciantes em Ruby.
67 | END_PARAGRAPH
68 | end
69 |
70 | para do <<-END_PARAGRAPH
71 | Eu, Fabio Akita, surgi
72 | com esta sugestão em Janeiro de 2008. Fiz o anúncio no meu blog e na lista rails-br e foi um
73 | movimento incrívei: dezenas de voluntários se candidataram a ajudar. Graças a isso a tradução
74 | e revisão não durou uma semana! Fico extremamente satisfeito em ter essa amostra da
75 | comunidade se auto-ajudando. Espero ter a oportunidade de conduzir mais trabalhos desta
76 | natureza.
77 | END_PARAGRAPH
78 | end
79 |
80 | para do <<-END_PARAGRAPH
81 | Meus agradecimentos e parabéns aos tradutores/revisores:
82 | Danilo Sato,
83 | Davi Vidal,
84 | Reginaldo Russinholi,
85 | Oliver Azevedo Barnes,
86 | Vitor Peres,
87 | Paulo Fernando Larini,
88 | Massimiliano Giroldi,
89 | Ricardo Yasuda,
90 | Lucas Húngaro,
91 | Anderson Leite.
92 |
93 | Agradeço também a todos que se voluntariaram, mas havia mais colaboradores que capítulos para
94 | traduzir e sobrou gente :-) Acho que é um bom sinal!
95 | END_PARAGRAPH
96 | end
97 |
98 | para do <<-END_PARAGRAPH
99 | Agradecimentos também ao Júlio Santos Monteiro por dar uma "casa" oficial a este trabalho no
100 | web site http://aprendaaprogramar.rubyonrails.com.br.
101 | END_PARAGRAPH
102 | end
103 |
104 | para do <<-END_PARAGRAPH
105 | Esperamos que o resultado deste trabalho seja de grande valia tanto a estudantes quanto
106 | a qualquer um que queira ensinar outros a programar.
107 | END_PARAGRAPH
108 | end
109 | puts HLINE
110 |
111 | h2 { 'Um lugar para o futuro programador começar' }
112 | para do <<-END_PARAGRAPH
113 | Eu acho que tudo isso começou em 2002. Eu estava pensando
114 | em ensinar programação, e como uma grande linguagem como
115 | Ruby seria ótima para aprender a como programar. Quer dizer, nós estávamos
116 | todos excitados com Ruby pelo seu poder, elegância e por ser realmente divertido,
117 | mas me pareceu que ele também seria um excelente guia para aprender a programar.
118 | END_PARAGRAPH
119 | end
120 | para do <<-END_PARAGRAPH
121 | Infelizmente, não havia muita documentação sobre Ruby
122 | destinada aos iniciantes naquela época. Alguns de nós,
123 | na comunidade, estávamos falando sobre como um tutorial
124 | "Ruby for the Nuby" era necessário,
125 | e, mais genericamente, um tutorial ensinando a programar, como um todo.
126 | Quanto mais eu pensava nisso, mais eu tinha a dizer (o que me surpreendeu
127 | um pouco). Até que alguém finalmente disse: "Chris, porque você
128 | não escreve um tutorial ao invés de ficar falando sobre isso?".
129 | Então eu o fiz.
130 | END_PARAGRAPH
131 | end
132 | para do <<-END_PARAGRAPH
133 | E isso não foi muito bom. Eu tive todas essas boas idéias que eram boas
134 | em teoria, mas a real tarefa de fazer um grande tutorial
135 | para não-programadores foi muito mais desafiadora
136 | do que eu poderia prever. (Quer dizer, pareciam boas para mim, mas eu já
137 | sabia como programar.)
138 | END_PARAGRAPH
139 | end
140 | para do <<-END_PARAGRAPH
141 | O que me salvou foi que eu fiz com que fosse fácil para as pessoas
142 | falarem comigo, e eu sempre tentei ajudar as pessoas quando elas empacavam.
143 | Quando eu via um monte de gente empacando em uma parte,
144 | eu a reescrevia. Isso deu muito trabalho, mas lentamente foi se tornando melhor
145 | e melhor.
146 | END_PARAGRAPH
147 | end
148 | para do <<-END_PARAGRAPH
149 | Alguns anos depois, isso estava ficando realmente bom. :-) Tão bom,
150 | na verdade, que eu já estava pronto para anunciar sua finalização e
151 | partir para outra coisa. E justamente nesse instante houve a
152 | oportunidade de transformar esse tutorial em um livro. Uma vez que o básico
153 | já estava pronto, eu achei que não haveria maiores problemas.
154 | Eu apenas precisaria esclarecer umas coisas, adicionar alguns exercícios extras,
155 | talvez mais alguns exemplos, um pouquinho mais de capítulos, enviar ele para
156 | uns 50 revisores...
157 | END_PARAGRAPH
158 | end
159 | para do <<-END_PARAGRAPH
160 | Isso me tomou outro ano, mas agora eu acho que está realmente
161 | muito bom, grande parte graças às centenas
162 | de boas almas que me ajudaram a escrever este livro.
163 | END_PARAGRAPH
164 | end
165 | para do <<-END_PARAGRAPH
166 | O que está nesse site é o tutorial original, quase inalterado
167 | desde 2004. Para o melhor e mais atualizado, você pode
168 | querer dar uma olhada no livro.
169 | END_PARAGRAPH
170 | end
171 | puts HLINE
172 | h2 { 'Notas Para Professores' }
173 | para do <<-END_PARAGRAPH
174 | Há algumas normas de conduta que eu tentei seguir.
175 | Eu acho que elas tornam o processo de aprendizado muito mais suave;
176 | ensinar a programar já é difícil por si só. Se você está
177 | ensinando ou guiando alguém pelas vias hackers, essas idéias podem lhe ajudar também.
178 | END_PARAGRAPH
179 | end
180 | para do <<-END_PARAGRAPH
181 | Primeiramente, eu tentei separar os conceitos o máximo possível,
182 | assim o estudante tem que aprender apenas um conceito de cada vez.
183 | Isso foi difícil no começo, mas um pouco mais fácil
184 | depois que eu peguei a prática. Algumas coisas devem ser faladas
185 | antes de outras, mas eu fiquei impressionado com quão pouca
186 | hierarquia de precedência realmente existe. Eventualmente, eu apenas tive que
187 | seguir uma ordem, e eu tentei arrumar as coisas de tal maneira
188 | que cada nova seção fosse motivada pela anterior.
189 | END_PARAGRAPH
190 | end
191 | para do <<-END_PARAGRAPH
192 | Outro princípio que eu tinha em mente era de ensinar apenas uma maneira
193 | de fazer alguma coisa. Isso é um benefício óbvio em um tutorial
194 | para pessoas que nunca programaram antes. Por um motivo:
195 | é mais fácil aprender uma maneira de fazer uma coisa do que duas. Porém
196 | o benefício mais importante é que quanto menos coisas você
197 | ensinar a um novo programador, mais criativo e esperto
198 | ele tem que ser na programação. Já que muito da programação
199 | é resolução de problemas, torna-se crucial o encorajamento em todos os estágios
200 | possíveis.
201 | END_PARAGRAPH
202 | end
203 | para do <<-END_PARAGRAPH
204 | Eu tentei traçar um paralelo entre os conceitos de programação
205 | com os conceitos que um novo programador já possui;
206 | para apresentar as idéias de uma maneira que o entendimento seja
207 | intuitivo, ao invés do tutorial despejar apenas informações.
208 | Programação Orientada a Objetos faz isso, por si só, muito bem.
209 | Eu fui capaz de me referir a "objetos" e diferentes "tipos de objetos"
210 | muito rapidamente nesse tutorial, soltando tais informações nos mais
211 | inocentes momentos. Eu não falei nada do tipo "tudo em Ruby é um objeto"
212 | ou "números e strings são tipos de objetos", porque essas
213 | coisas não dizem nada para um novo programador. Ao invés disso,
214 | eu vou falar sobre strings (e não sobre "objetos do tipo string"),
215 | e algumas vezes eu vou me referir a "objetos", apenas no sentido de "as coisas
216 | nesses programas". O fato de que todas essas coisas em Ruby são
217 | objetos fez com que esse tipo de inconsistência da minha parte funcionasse tão bem.
218 | END_PARAGRAPH
219 | end
220 | para do <<-END_PARAGRAPH
221 | Sobretudo, eu procurei fugir do jargão desnecessário da
222 | OO, eu procurei ter certeza de que, se eles têm de aprender
223 | uma palavra, que aprendam a certa (Eu não quero que eles
224 | tenham de aprender em duplicidade, certo?). Então, eu chamei
225 | tudo de "strings", e não "texto". Métodos precisam ser chamados
226 | de alguma coisa, então eu os chamei de métodos.
227 | END_PARAGRAPH
228 | end
229 | para do <<-END_PARAGRAPH
230 | A medida que os exercícios foram sendo concebidos, eu achei
231 | que estava com bons exercícios, mas você nunca pode colocar
232 | exercícios demais. Honestamente, eu acho que eu gastei quase
233 | metade do meu tempo apenas tentando fazer exercícios divertidos
234 | e interessantes. Exercícios entediantes apenas aniquilam qualquer
235 | desejo de programar, enquanto que o exercício perfeito cria
236 | aquela coceira no programador novo que ele não consegue ficar sem
237 | coçar. Resumindo, não gaste muito tempo tentando fazer exercícios bons.
238 | END_PARAGRAPH
239 | end
240 | puts HLINE
241 | h2 { 'Sobre o Tutorial Original' }
242 | para do <<-END_PARAGRAPH
243 | As páginas do tutorial (esta página, inclusive) são geradas por um
244 | grande programa em Ruby,
245 | claro. :-)
246 | Assim, elas possuem recursos elegantes. Por exemplo, todos os
247 | exemplos de código são realmente executados toda vez que você
248 | vê a página, e a saída dos mesmos é a saída que eles geram.
249 | Eu acredito que essa é a maneira mais fácil, melhor e, certamente, a
250 | mais legal de ter certeza que todo o código mostrado
251 | funciona exatamente como eu digo que funciona.
252 | Você não precisa se preocupar com a possibilidade de eu ter copiado
253 | a saída de um exemplo erroneamente ou esquecido de testar um código:
254 | tudo é testado na hora que você vê. Então, na seção de geradores de
255 | números aleatórios, você vai ver que os números mudam sempre... lindo.
256 | (Eu usei um truque parecido na hora de escrever o livro, mas é óbvio que isso
257 | é muito mais aparente aqui no tutorial.)
258 | END_PARAGRAPH
259 | end
260 | h2 { "Sobre o Material Traduzido" }
261 | para do <<-END_PARAGRAPH
262 | O código original descrito por Chris Pine acima, era uma versão simples e implementada sobre
263 | CGI. Em total ritmo de 2008, eu mesmo (Fabio Akita) modifiquei esse código. Sem muitas
264 | modificações sobre o original, transportei o código para rodar sobre Rails 2.0.2.
265 | END_PARAGRAPH
266 | end
267 |
268 | para do <<-END_PARAGRAPH
269 | Esse código está todo disponível no GitHub, neste endereço:
270 | END_PARAGRAPH
271 | end
272 |
273 | para do <<-END_PARAGRAPH
274 | https://github.com/jmonteiro/aprendaaprogramar
275 | END_PARAGRAPH
276 | end
277 |
278 | para do <<-END_PARAGRAPH
279 | Por motivos de performance, os códigos (que localmente são realmente executados em tempo real
280 | conforme Chris explicou) não são executados online, sendo uma cópia estática. Para ter todos os
281 | benefícios do programa em tempo real, baixe o código para rodar sobre Rails.
282 | END_PARAGRAPH
283 | end
284 | para do
285 | ''+
286 | '
'+
287 | ''
288 | end
289 | puts HLINE
290 | h2 { 'Agradecimentos' }
291 | para do <<-END_PARAGRAPH
292 | Finalizando, eu gostaria de agradecer a todos da lista ruby-talk
293 | por suas idéis e pelo encorajamento, aos meus maravilhosos
294 | revisores, por sua ajuda em fazer o livro muito melhor do que
295 | eu poderia fazer sozinho, especialmente à minha querida esposa,
296 | por ser minha principal revisora/testadora/cobaia/musa, ao Matz,
297 | por ter criado essa fabulosa linguagem, e aos Pragmatic Programmers, por
298 | me falar sobre a linguagem—e, é claro, por publicar meu livro!
299 | END_PARAGRAPH
300 | end
301 | para do <<-END_PARAGRAPH
302 | Se você notar qualquer erro ou falha de digitação, se tiver
303 | qualquer comentário ou sugestão, ou um bom exercício que eu possa
304 | incluir, por favor me avise (se você falar
305 | inglês) ou, se preferir falar em português,
306 | avise o Júlio Monteiro.
307 | END_PARAGRAPH
308 | end
309 | end
310 |
311 | puts HLINE
312 | para(:style=>'padding-bottom: 20px;') { "© 2003-#{Time.now.year} Chris Pine" }
313 | end # contentPane
314 | end # pageWidth
315 | end # body
316 | end # html
317 | end
318 | end
319 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/menu.rb:
--------------------------------------------------------------------------------
1 | module Menu
2 | # menu helpers
3 |
4 | def menuBookLink
5 | para(:class=>'funnyMenuText fancyMenuText', :style=>'font-size: 12px; font-family: times, serif;') { 'a versão' }
6 | para(:class=>'funnyMenuText fancyMenuText', :style=>'font-size: 12px; font-family: times, serif;') { 'melhorada' }
7 | para(:class=>'funnyMenuText fancyMenuText', :style=>'font-size: 12px; font-family: times, serif; letter-spacing: 6px; font-variant: small-caps;') { 'estendida' }
8 | puts ""
9 | img(:width=>'100', :height=>'120', :src=>'images/LTP_cover.jpg')
10 | puts ''
11 | end
12 |
13 | def menuTOC
14 | para(:class=>'funnyMenuText') { '« o tutorial original »' }
15 |
16 | ol(:start=>'0', :style=>'padding-top: 15px; padding-bottom: 15px;') do
17 | @chapters.sort_by{|x| x[0]}.each do |aChapNum, aChapter|
18 | if aChapNum != 'format'
19 | li { makeLink(aChapter[0],aChapter[1]) }
20 | end
21 | end
22 | end
23 |
24 | para do <<-END_PARAGRAPH
25 | (Versão Original
26 | por Chris Pine.)
27 | END_PARAGRAPH
28 | end
29 | para do <<-END_PARAGRAPH
30 | (Tradução em Japonês
31 | por Shin Nishiyama.)
32 | END_PARAGRAPH
33 | end
34 | para do <<-END_PARAGRAPH
35 | (Tradução em Francês
36 | por Jean‑Pierre ANGHEL.)
37 | END_PARAGRAPH
38 | end
39 | para do <<-END_PARAGRAPH
40 | (Tradução em Russo
41 | por Mikhail Shokhirev.)
42 | END_PARAGRAPH
43 | end
44 | para do <<-END_PARAGRAPH
45 | (Tradução em Dinamarquês
46 | por Gunner Carstens.)
47 | END_PARAGRAPH
48 | end
49 | para do <<-END_PARAGRAPH
50 | (Tradução em Bósnio
51 | por Rusmir Gadžo.)
52 | END_PARAGRAPH
53 | end
54 | end
55 | end
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/methods.rb:
--------------------------------------------------------------------------------
1 | module Methods
2 | #
3 | # METHODS
4 | #
5 |
6 | def generateMethods
7 | para do <<-END_PARAGRAPH
8 | Até agora nós vimos uma porção de métodos diferentes,
9 | #{code 'puts'} e #{code 'gets'}
10 | dentre outros (Teste Surpresa: Liste todos
11 | os métodos que vimos até agora!
12 | Foram dez deles; a resposta está mais embaixo.),
13 | mas nós não conversamos realmente sobre o que são métodos.
14 | Nós sabemos o que eles fazem, mas não sabemos o que eles são.
15 | END_PARAGRAPH
16 | end
17 | para do <<-END_PARAGRAPH
18 | Mas, na verdade, isso é o que eles são: coisas
19 | que fazem coisas. Se objetos (como strings,
20 | inteiros e floats) são os substantivos na linguagem Ruby,
21 | os métodos são como os verbos.
22 | E, ao contrário do Português (em que há sujeitos indefinidos
23 | e outras construções esotéricas), você não pode ter um
24 | verbo sem um substantivo para executar o verbo. Mas mesmo
25 | o Português trata a ausência de um substantivo como exceção:
26 | por exemplo, contar o tempo não é algo que simplesmente acontece;
27 | um relógio (ou cronômetro, ou algo parecido) deve fazê-lo. Em
28 | Português diríamos: "O relógio conta o tempo". Em Ruby dizemos
29 | #{code 'relogio.tiquetaque'} (presumindo que #{code 'relogio'}
30 | é um objeto Ruby, claro).
31 | Programadores podem dizer que estamos "chamando o método
32 | #{code 'tiquetaque'} do #{code 'relogio'},"
33 | ou que "chamamos #{code 'tiquetaque'} no #{code 'relogio'}."
34 | END_PARAGRAPH
35 | end
36 | para do <<-END_PARAGRAPH
37 | E então, você respondeu o quiz? Ótimo. Bem, tenho
38 | certeza que você lembrou dos métodos
39 | #{code 'puts'}, #{code 'gets'} e #{code 'chomp'},
40 | que acabamos de ver. Você também provavelmente
41 | lembrou dos métodos de conversão,
42 | #{code 'to_i'}, #{code 'to_f'}
43 | e #{code 'to_s'}. No entanto, você descobriu os
44 | outros quatro? Pois não eram ninguém menos
45 | que nossos velhos amigos da matemática, #{code '+'},
46 | #{code '-'}, #{code '*'} e #{code '/'}!
47 | END_PARAGRAPH
48 | end
49 | para do <<-END_PARAGRAPH
50 | Como eu estava dizendo, todo método precisa de um objeto.
51 | Geralmente é fácil dizer qual objeto está executando o
52 | método: é aquilo que vem logo antes do ponto, como
53 | no nosso exemplo do #{code 'relogio.tiquetaque'}, ou em
54 | #{code '101.to_s'}.
55 | Às vezes, no entanto, isso não é tão óbvio; como com os
56 | métodos aritméticos. A bem da verdade,
57 | #{code '5 + 5'} é realmente apenas um atalho para se
58 | escrever #{code '5.+ 5'}.
59 | Por exemplo:
60 | END_PARAGRAPH
61 | end
62 | prog do <<-END_CODE
63 | puts 'olá '.+ 'mundo'
64 | puts (10.* 9).+ 9
65 | END_CODE
66 | end
67 | para do <<-END_PARAGRAPH
68 | Não é muito bonito, então nós nunca mais vamos escrever desse jeito;
69 | no entanto, é importante entender o que realmente está
70 | acontecendo.
71 | (Na minha máquina, isso também me dá um aviso:
72 | #{output 'warning: parenthesize argument(s) for future version'}.
73 | O código ainda rodou sem problemas, mas ele está me dizendo que está com
74 | problemas para descobrir o que eu quis dizer, e pedindo para usar mais parênteses no
75 | futuro).
76 | Isso também nos dá um entendimento mais profundo sobre por que
77 | podemos fazer #{code "'porco'*5"} mas não #{code "5*'porco'"}:
78 | #{code "'porco'*5"} está dizendo ao #{code "'porco'"} para se
79 | multiplicar, mas #{code "5*'porco'"} está pedindo ao #{code '5'}
80 | que se multiplique. #{code "'porco'"} sabe como fazer
81 | #{code '5'} cópias de si mesmo e juntá-las; no entanto, #{code '5'}
82 | vai ter muito mais dificuldade para fazer
83 | #{code "'porco'"} cópias de si mesmo e juntá-las.
84 | END_PARAGRAPH
85 | end
86 | para do <<-END_PARAGRAPH
87 | E, claro, nós ainda temos o #{code 'puts'}
88 | e o #{code 'gets'} para explicar. Onde estão seus
89 | objetos? Em Português, você pode às vezes omitir o
90 | substantivo; por exemplo, se um vilão grita "Morra!",
91 | o substantivo implícito é a pessoa com quem ele está
92 | gritando. Em Ruby, se dissermos
93 | #{code "puts 'ser ou não ser'"}, o que
94 | eu realmente estou dizendo é
95 | #{code "self.puts 'ser ou não ser'"}.
96 | Então o que é #{code 'self'}? É uma variável especial
97 | que aponta para o objeto onde você está.
98 | Nós nem sabemos como estar em um
99 | objeto ainda, mas até descobrirmos, nós
100 | estaremos sempre em um grande objeto que é...
101 | o programa inteiro! E para nossa sorte, o
102 | programa tem alguns métodos próprios, como
103 | #{code 'puts'} e #{code 'gets'}.
104 | Preste atenção:
105 | END_PARAGRAPH
106 | end
107 | prog do <<-END_CODE
108 | naoAcreditoQueFizUmNomeDeVariavelTaoGrandeApenasParaGuardarUm3 = 3
109 | puts naoAcreditoQueFizUmNomeDeVariavelTaoGrandeApenasParaGuardarUm3
110 | self.puts naoAcreditoQueFizUmNomeDeVariavelTaoGrandeApenasParaGuardarUm3
111 | END_CODE
112 | end
113 | para do <<-END_PARAGRAPH
114 | Se você não acompanhou tudo o que aconteceu, não tem problema.
115 | A coisa importante para aprender disso tudo é que cada
116 | métodos está sendo executado pelo mesmo objeto, mesmo
117 | que ele não esteja na sua frente. Se você entender isso, então
118 | está preparado.
119 | END_PARAGRAPH
120 | end
121 | h2 {'Métodos Elegantes da String'}
122 | para do <<-END_PARAGRAPH
123 | Vamos aprender alguns métodos divertidos da string.
124 | Você não precisa memorizar todos eles; você pode
125 | apenas olhar esta página novamente se esquecê-los.
126 | Eu só quero mostrar uma pequena parte do que
127 | as strings podem fazer. Na verdade, eu mesmo não lembro
128 | da metade dos métodos da string—mas não tem
129 | problema, pois existem ótimas referências na internet
130 | com todos os métodos da string listados e explicados.
131 | (Vou mostrar onde encontrá-los no final deste tutorial.)
132 | Pra falar a verdade, eu nem quero saber todos
133 | os métodos da string; é como saber todas as palavras do
134 | dicionário. Eu posso falar Português muito bem sem saber
135 | todas as palavras do dicionário... e esse não é exatamente
136 | o seu propósito? Para que você não precise
137 | saber tudo que está nele?
138 | END_PARAGRAPH
139 | end
140 | para do <<-END_PARAGRAPH
141 | Então, nosso primeiro método da string é o #{code 'reverse'},
142 | que nos dá uma versão ao contrário da string:
143 | END_PARAGRAPH
144 | end
145 | prog do <<-END_CODE
146 | var1 = 'pare'
147 | var2 = 'radar'
148 | var3 = 'Voce consegue pronunciar esta frase ao contrario?'
149 |
150 | puts var1.reverse
151 | puts var2.reverse
152 | puts var3.reverse
153 | puts var1
154 | puts var2
155 | puts var3
156 | END_CODE
157 | end
158 | para do <<-END_PARAGRAPH
159 | Como você pode ver, #{code 'reverse'} não inverte a
160 | string original; ela apenas faz uma nova versão ao contrário dela.
161 | É por isso que #{code 'var1'} ainda é #{code "'pare'"}
162 | mesmo após a chamada a #{code 'reverse'} em #{code 'var1'}.
163 | END_PARAGRAPH
164 | end
165 | para do <<-END_PARAGRAPH
166 | Outro método da string é #{code 'length'}, que nos diz
167 | o número de caracteres (incluindo espaços) na string:
168 | END_PARAGRAPH
169 | end
170 | prog ['Christopher David Pine'] do <<-END_CODE
171 | puts 'Qual o seu nome completo?'
172 | nome = gets.chomp
173 | puts 'Você sabia que seu nome possui ' + nome.length + ' caracteres, ' + nome + '?'
174 | END_CODE
175 | end
176 | para do <<-END_PARAGRAPH
177 | Uh-oh! Algo deu errado, e parece que isso aconteceu após a linha
178 | #{code 'nome = gets.chomp'}... Você enxerga o problema? Veja se consegue descobrir.
179 | END_PARAGRAPH
180 | end
181 | para do <<-END_PARAGRAPH
182 | O problema está em #{code 'length'}: ele lhe dá um número, mas queremos uma string.
183 | Fácil, vamos colocar um #{code 'to_s'} (e cruzar os dedos):
184 | END_PARAGRAPH
185 | end
186 | prog ['Christopher David Pine'] do <<-END_CODE
187 | puts 'Qual o seu nome completo?'
188 | nome = gets.chomp
189 | puts 'Você sabia que seu nome possui ' + nome.length.to_s + ' caracteres, ' + nome + '?'
190 | END_CODE
191 | end
192 | para do <<-END_PARAGRAPH
193 | Não, eu não sabia disso. Nota: este é o número de
194 | caracteres no meu nome, não o número de letras
195 | (conte-as). Eu acho que conseguimos escrever um programa que
196 | pergunta seu primeiro nome, nome do meio e sobrenome individualmente e
197 | some todos os tamanhos... Ei, por que você não faz isso? Vá em frente,
198 | eu espero.
199 | END_PARAGRAPH
200 | end
201 | para do <<-END_PARAGRAPH
202 | Pronto? Bom! É um programa legal, não é?
203 | Depois de mais uns capítulos, entretanto, você vai ficar maravilhado com
204 | o que conseguirá fazer.
205 | END_PARAGRAPH
206 | end
207 | para do <<-END_PARAGRAPH
208 | Existem alguns métodos da string que conseguem mudar a caixa (maiúsculas
209 | e minúsculas) da sua string. #{code 'upcase'} muda todas as letras minúsculas
210 | para maiúsculas, e #{code 'downcase'} muda todas as letras maiúsculas para
211 | minúsculas. #{code 'swapcase'} troca a caixa de todas as letras da string e,
212 | finalmente, #{code 'capitalize'} é parecido com #{code 'downcase'}, exceto que
213 | ele troca o primeiro caractere para maiúsculo (se for uma letra).
214 | END_PARAGRAPH
215 | end
216 | prog do <<-END_CODE
217 | letras = 'aAbBcCdDeE'
218 | puts letras.upcase
219 | puts letras.downcase
220 | puts letras.swapcase
221 | puts letras.capitalize
222 | puts ' a'.capitalize
223 | puts letras
224 | END_CODE
225 | end
226 | para do <<-END_PARAGRAPH
227 | Coisas bem simples. Como você pode ver na linha
228 | #{code "puts ' a'.capitalize"}, o método #{code 'capitalize'}
229 | apenas deixa em maiúsculo o primeiro caractere, não a primeira
230 | letra. Também, como vimos anteriormente, durante todas essas chamadas
231 | de métodos, #{code 'letras'} continuou inalterada. Eu não quero me alongar nesse
232 | ponto, mas é importante entender. Existem alguns métodos que mudam o
233 | objeto associado, mas ainda não vimos nenhum, e nem iremos ver durante algum tempo.
234 | END_PARAGRAPH
235 | end
236 | para do <<-END_PARAGRAPH
237 | O último método elegante da string que iremos ver é
238 | para formatação visual.
239 | O primeiro, #{code 'center'}, adiciona espaços no começo e no
240 | fim da string para torná-la centralizada. No entanto, assim como
241 | você precisa dizer ao #{code 'puts'} o que quer que seja impresso, e ao
242 | #{code '+'} o que quer que seja adicionado, você precisa dizer ao
243 | #{code 'center'} a largura total da string a ser centralizada. Então
244 | se eu quiser centralizar as linhas de um poema, eu faria assim:
245 | END_PARAGRAPH
246 | end
247 | prog do <<-END_CODE
248 | larguraDaLinha = 50
249 | puts( 'Old Mother Hubbard'.center(larguraDaLinha))
250 | puts( 'Sat in her cupboard'.center(larguraDaLinha))
251 | puts( 'Eating her curds an whey,'.center(larguraDaLinha))
252 | puts( 'When along came a spider'.center(larguraDaLinha))
253 | puts( 'Which sat down beside her'.center(larguraDaLinha))
254 | puts('And scared her poor shoe dog away.'.center(larguraDaLinha))
255 | END_CODE
256 | end
257 | para do <<-END_PARAGRAPH
258 | Hum... Eu não acho que essa rima é assim, mas sou muito preguiçoso
259 | para procurar. (Também, eu queria alinhar a parte do
260 | #{code '.center larguraDaLinha'}, por isso acrescentei espaços extra antes
261 | das strings. Isso é só por que acho que fica mais bonito assim.
262 | Programadores geralmente têm opiniões fortes sobre o que é
263 | bonito num programa, e eles geralmente discordam sobre o assunto.
264 | Quanto mais você programar, mais vai descobrir seu próprio estilo).
265 | Falando em ser preguiçoso, a preguiça nem sempre é algo ruim na programação.
266 | Por exemplo, viu como eu guardei a largura do poema numa variável
267 | #{code 'larguraDaLinha'}? Fiz isso pois se quiser tornar o poema mais
268 | largo mais tarde, só precisarei mudar a primeira linha do programa,
269 | ao invés de todas as linhas que são centralizadas. Com um poema muito
270 | longo, isso poderia me poupar um bom tempo. Esse tipo de preguiça é na
271 | verdade uma virtude na programação.
272 | END_PARAGRAPH
273 | end
274 | para do <<-END_PARAGRAPH
275 | Então, em relação à centralização... você deve ter percebido que não está
276 | tão bonito quanto um processador de texto teria feito. Se você realmente
277 | quer centralização perfeita (e talvez uma fonte melhor), então você
278 | deveria apenas usar um processador de texto! Ruby é uma ferramenta
279 | maravilhosa, mas nenhuma ferramenta é a ferramenta certa para
280 | qualquer trabalho.
281 | END_PARAGRAPH
282 | end
283 | para do <<-END_PARAGRAPH
284 | Os outros dois métodos de formatação da string são #{code 'ljust'} e
285 | #{code 'rjust'}, que fazem o texto justificado à esquerda e
286 | justificado à direita. Eles são parecidos com o #{code 'center'},
287 | exceto que eliminam os espaços em branco da string do lado direito e esquerdo,
288 | respectivamente. Vamos ver os três em ação:
289 | END_PARAGRAPH
290 | end
291 | prog do <<-END_CODE
292 | larguraDaLinha = 40
293 | str = '--> text <--'
294 | puts str.ljust larguraDaLinha
295 | puts str.center larguraDaLinha
296 | puts str.rjust larguraDaLinha
297 | puts str.ljust (larguraDaLinha/2) + str.rjust (larguraDaLinha/2)
298 | END_CODE
299 | end
300 | h2 {'Umas Coisinhas Para Tentar'}
301 | para do <<-END_PARAGRAPH
302 | • Escreva um programa do Chefe Zangado. Ele deve perguntar o que você quer de forma rude.
303 | Qualquer que seja a sua resposta, o Chefe Zangado vai gritar de volta para você, e então
304 | despedi-lo. Por exemplo, se você digitar #{input 'Eu quero um aumento.'}, ele deve gritar
305 | de volta #{output 'O QUE VOCÊ QUER DIZER COM "EU QUERO UM AUMENTO."?!? VOCÊ ESTÁ DESPEDIDO!!'}
306 | END_PARAGRAPH
307 | end
308 | para do <<-END_PARAGRAPH
309 | • Eis aqui algo para você fazer para brincar um pouco mais com
310 | #{code 'center'}, #{code 'ljust'} e #{code 'rjust'}: Escreva um programa
311 | que irá mostrar um Índice de forma que fique parecido com:
312 | END_PARAGRAPH
313 | end
314 | puts '' +
315 | ' Tabela de Conteúdo ' + $/ +
316 | ' ' + $/ +
317 | 'Capítulo 1: Números página 1' + $/ +
318 | 'Capítulo 2: Letras página 72' + $/ +
319 | 'Capítulo 3: Variáveis página 118' + $/ +
320 | '
'
321 | h2 {'Matemática Avançada'}
322 | para do <<-END_PARAGRAPH
323 | (Esta seção é totalmente opcional. Ela assume um certo nível
324 | de conhecimento matemático. Se você não estiver interessado, você pode
325 | ir direto para o #{makeLink 'Controle de Fluxo', :generateFlowControl}
326 | sem nenhum problema. No entanto, uma breve passada pela seção de
327 | Números Aleatórios pode ser útil.)
328 | END_PARAGRAPH
329 | end
330 | para do <<-END_PARAGRAPH
331 | Não há tantos métodos nos números quanto nas strings
332 | (apesar de eu ainda não ter decorado todos). Aqui, iremos olhar o
333 | resto dos métodos de aritmética, um gerador de números aleatórios e
334 | o objeto #{code 'Math'}, com seus métodos trigonométricos e
335 | transcendentais.
336 | END_PARAGRAPH
337 | end
338 | h2 {'Mais Aritimética'}
339 | para do <<-END_PARAGRAPH
340 | Os outros dois métodos aritméticos são #{code '**'} (exponenciação)
341 | e #{code '%'} (módulo). Então se você quisesse dizer "cinco ao quadrado"
342 | em Ruby, você escreveria #{code '5**2'}. Você também pode usar
343 | floats para seu expoente, então se você quiser a raiz quadrada de 5,
344 | você pode escrever #{code '5**0.5'}. O método módulo lhe dá o resto da
345 | divisão por um número. Então, por exemplo, se eu divido 7 por 3,
346 | eu tenho 2 com resto 1. Vamos vê-los em ação num programa:
347 | END_PARAGRAPH
348 | end
349 | prog do <<-END_CODE
350 | puts 5**2
351 | puts 5**0.5
352 | puts 7/3
353 | puts 7%3
354 | puts 365%7
355 | END_CODE
356 | end
357 | para do <<-END_PARAGRAPH
358 | Pela última linha, aprendemos que um ano (não-bissexto) tem um certo
359 | número de semanas, mais um dia. Então se seu aniversário caiu numa
360 | terça-feira este ano, ele será numa quarta-feira no ano que vem.
361 | Você também pode usar floats com o método módulo. Basicamente, ele
362 | funciona da única maneira razoável que consegue... Mas eu vou deixar
363 | você brincar um pouco com isso.
364 | END_PARAGRAPH
365 | end
366 | para do <<-END_PARAGRAPH
367 | Tem um último método para ser mencionado antes de vermos o gerador de
368 | números aleatórios: #{code 'abs'}. Ele simplesmente pega o valor
369 | absoluto de um número:
370 | END_PARAGRAPH
371 | end
372 | prog do <<-END_CODE
373 | puts((5-2).abs)
374 | puts((2-5).abs)
375 | END_CODE
376 | end
377 | h2 {'Números Aleatórios'}
378 | para do <<-END_PARAGRAPH
379 | Ruby vem com um gerador de números aleatórios bem legal. O método que
380 | escolhe aleatoriamente um número é o #{code 'rand'}. Se você chamar #{code 'rand'}
381 | simplesmente assim, você vai ter um float maior ou igual a #{code '0.0'} e menor
382 | que #{code '1.0'}. Se você der um inteiro (#{code '5'} por exemplo) para o #{code 'rand'},
383 | ele vai te dar um inteiro maior ou igual a #{code '0'} e menor que #{code '5'} (então são
384 | cinco números possíveis, de #{code '0'} até #{code '4'}).
385 | END_PARAGRAPH
386 | end
387 | para do <<-END_PARAGRAPH
388 | Vamos ver o #{code 'rand'} em ação. (Se você recarregar esta página, estes números vão
389 | mudar a cada vez. Você sabia que eu estou realmente rodando estes programas, não sabia?)
390 | END_PARAGRAPH
391 | end
392 | prog do <<-END_CODE
393 | puts rand
394 | puts rand
395 | puts rand
396 | puts(rand(100))
397 | puts(rand(100))
398 | puts(rand(100))
399 | puts(rand(1))
400 | puts(rand(1))
401 | puts(rand(1))
402 | puts(rand(99999999999999999999999999999999999999999999999999999999999))
403 | puts('O homem do tempo disse que existe '+rand(101).to_s+'% de chance de chover,')
404 | puts('mas você não pode nunca confiar num homem do tempo.')
405 | END_CODE
406 | end
407 | para do <<-END_PARAGRAPH
408 | Perceba que eu usei #{code 'rand(101)'} para conseguir os números de #{code '0'}
409 | até #{code '100'}, e que #{code 'rand(1)'} sempre retorna #{code '0'}. Não entender o
410 | intervalo dos possíveis valores retornados é o maior erro que eu vejo as pessoas
411 | cometerem ao usar #{code 'rand'}; mesmo programadores profissionais; mesmo em
412 | produtos terminados que você pode comprar na loja. Eu inclusive tive um tocador de CD
413 | que, se configurado para "Tocar Aleatoriamente", iria tocar todas as músicas menos
414 | a última... (Eu imagino o que aconteceria se eu colocasse um CD com apenas uma música
415 | nele?)
416 | END_PARAGRAPH
417 | end
418 | para do <<-END_PARAGRAPH
419 | As vezes você pode querer que #{code 'rand'} retorne os mesmos números aleatórios
420 | na mesma sequência em duas execuções diferentes do seu programa. (Por exemplo, uma vez eu
421 | estava usando números aleatórios gerados para criar um mundo gerado aleatoriamente num
422 | jogo de computador. Se eu encontrasse um mundo que eu realmente gostasse, talvez eu quisesse
423 | jogar nele novamente, ou mandá-lo para um amigo). Para isso, você precisa configurar
424 | a semente, que você consegue fazer com #{code 'srand'}. Desta forma:
425 | END_PARAGRAPH
426 | end
427 | prog do <<-END_CODE
428 | srand 1776
429 | puts(rand(100))
430 | puts(rand(100))
431 | puts(rand(100))
432 | puts(rand(100))
433 | puts(rand(100))
434 | puts ''
435 | srand 1776
436 | puts(rand(100))
437 | puts(rand(100))
438 | puts(rand(100))
439 | puts(rand(100))
440 | puts(rand(100))
441 | END_CODE
442 | end
443 | para do <<-END_PARAGRAPH
444 | Ele fará a mesma coisa sempre que você alimentá-lo com a mesma semente. Se você quer
445 | voltar a ter números diferentes (como acontece quando você nunca usa
446 | #{code 'srand'}), então apenas chame #{code 'srand 0'}. Isso alimenta o gerador com
447 | um número realmente estranho, usando (dentre outras coisas) a hora atual do seu
448 | computador, com precisão de milisegundos.
449 | END_PARAGRAPH
450 | end
451 | h2 {"O Objeto #{code 'Math'}"}
452 | para do <<-END_PARAGRAPH
453 | Finalmente, vamos olhar para o objeto #{code 'Math'}. Vamos começar de uma vez:
454 | END_PARAGRAPH
455 | end
456 | prog do <<-END_CODE
457 | puts(Math::PI)
458 | puts(Math::E)
459 | puts(Math.cos(Math::PI/3))
460 | puts(Math.tan(Math::PI/4))
461 | puts(Math.log(Math::E**2))
462 | puts((1 + Math.sqrt(5))/2)
463 | END_CODE
464 | end
465 | para do <<-END_PARAGRAPH
466 | A primeira coisa que você percebeu foi provavelmente a notação do #{code '::'}. Explicar
467 | o operador de escopo (que é o que ele é) está um pouco além do, uh... escopo
468 | deste tutorial. Não é nenhum trocadilho. Eu juro. Basta dizer que você pode usar
469 | #{code 'Math::PI'} exatamente da forma como você espera.
470 | END_PARAGRAPH
471 | end
472 | para do <<-END_PARAGRAPH
473 | Como você pode ver, #{code 'Math'} tem todas as coisas que você esperaria que
474 | uma calculadora científica decente tivesse. E, como sempre, os floats estão
475 | realmente perto de serem as respostas certas.
476 | END_PARAGRAPH
477 | end
478 | para do <<-END_PARAGRAPH
479 | Então vamos entrar no #{makeLink 'fluxo', :generateFlowControl}!
480 | END_PARAGRAPH
481 | end
482 | end
483 | end
484 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/numbers.rb:
--------------------------------------------------------------------------------
1 | module Numbers
2 | #
3 | # NUMBERS
4 | #
5 |
6 | def generateNumbers
7 | para do <<-END_PARAGRAPH
8 | Agora que você já #{makeLink('arranjou', :generateSetup)}
9 | tudo, vamos escrever um programa! Abra seu editor de texto
10 | favorito e digite o seguinte:
11 | END_PARAGRAPH
12 | end
13 | prog false do <<-END_CODE
14 | puts 1+2
15 | END_CODE
16 | end
17 | para do <<-END_PARAGRAPH
18 | Salve seu programa (sim, isso é um programa!) como #{input 'calc.rb'}
19 | (o .rb é o que normalmente colocamos no final de
20 | programas escritos em Ruby). Agora rode o seu programa digitando
21 | #{input 'ruby calc.rb'} na linha de comando. Ele deve ter posto
22 | #{output '3'} na sua tela. Viu como programar não é tão difícil?
23 | END_PARAGRAPH
24 | end
25 | h2 {'Introdução ao '+(code 'puts')}
26 | para do <<-END_PARAGRAPH
27 | O que é então que está acontecendo no programa? Tenho certeza que você
28 | é capaz de adivinhar o quê #{code '1+2'} faz; nosso programa é
29 | praticamente a mesma coisa que:
30 | END_PARAGRAPH
31 | end
32 | prog false do <<-END_CODE
33 | puts 3
34 | END_CODE
35 | end
36 | para do <<-END_PARAGRAPH
37 | #{code 'puts'} simplesmente escreve na tela tudo que
38 | vem depois dele.
39 | END_PARAGRAPH
40 | end
41 | h2 {'Inteiro e Float'}
42 | para do <<-END_PARAGRAPH
43 | Na maioria das linguagens de programação (e não é diferente no Ruby)
44 | números sem pontos decimais são chamados de inteiros, e
45 | números com pontos decimais normalmente são chamados de
46 | números de ponto-flutuante,
47 | ou mais singelamente, floats.
48 | END_PARAGRAPH
49 | end
50 | para do <<-END_PARAGRAPH
51 | Eis alguns inteiros:
52 | END_PARAGRAPH
53 | end
54 | prog false do <<-END_CODE
55 | 5
56 | -205
57 | 9999999999999999999999999
58 | 0
59 | END_CODE
60 | end
61 | para do <<-END_PARAGRAPH
62 | E aqui estão alguns floats:
63 | END_PARAGRAPH
64 | end
65 | prog false do <<-END_CODE
66 | 54.321
67 | 0.001
68 | -205.3884
69 | 0.0
70 | END_CODE
71 | end
72 | para do <<-END_PARAGRAPH
73 | Na prática, a maioria dos programas não usa floats;
74 | apenas inteiros.
75 | (Afinal, ninguém quer ler 7.4 emails, ou navegar 1.8 páginas,
76 | ou ouvir 5.24 músicas favoritas)
77 | Floats são usados mais freqüentemente para fins acadêmicos
78 | (experimentos de física e afins) e para gráficos 3D.
79 | Mesmo a maioria dos programas que lidam com dinheiro usam
80 | inteiros; eles só ficam contando as moedinhas!
81 | END_PARAGRAPH
82 | end
83 | h2 {'Aritmética Simples'}
84 | para do <<-END_PARAGRAPH
85 | Até agora, temos tudo que é necessário para uma calculadora simples.
86 | (Calculadoras sempre usam floats, então se você quer que seu
87 | computador aja como uma calculadora, você também deve usar floats.)
88 | Para adição e subtração, usamos + e -, como
89 | vimos. Para multiplicação, usamos *, e para divisão
90 | usamos /. A maioria dos teclados possui essas
91 | teclas no teclado numérico. Se você tem teclado menor ou um laptop,
92 | você pode usar Shift 8 e / (fica na mesma
93 | tecla que ?). Vamos tentar expandir um pouco nosso calc.rb.
94 | Digite o seguinte e depois rode.
95 | END_PARAGRAPH
96 | end
97 | prog [], 'Isto é o que o programa retorna:' do <<-END_CODE
98 | puts 1.0 + 2.0
99 | puts 2.0 * 3.0
100 | puts 5.0 - 8.0
101 | puts 9.0 / 2.0
102 | END_CODE
103 | end
104 | para do <<-END_PARAGRAPH
105 | (Os espaços no programa não são importantes; eles só deixam
106 | o código mais legível.) Bom, não foi lá muito surpreendente.
107 | Vamos tentar agora com inteiros.
108 | END_PARAGRAPH
109 | end
110 | prog [], 'Basicamente a mesma coisa, não é?' do <<-END_CODE
111 | puts 1+2
112 | puts 2*3
113 | puts 5-8
114 | puts 9/2
115 | END_CODE
116 | end
117 | para do <<-END_PARAGRAPH
118 | Ahn... tirando aquele último ali!
119 | Quando você faz aritmética com inteiros, você recebe respostas em
120 | inteiros. Quando seu computador não sabe dar a resposta "certa", ele
121 | sempre arredonda para baixo. (Claro, #{output '4'} é a
122 | resposta certa em aritmética de inteiros para #{code '9/2'}; só
123 | pode não ser o que você estava esperando.)
124 | END_PARAGRAPH
125 | end
126 | para do <<-END_PARAGRAPH
127 | Talvez você esteja se perguntado para que divisão de inteiros serve.
128 | Bem, vamos dizer que você vai ao cinema, mas só tem $ 9. Aqui em
129 | Portland, você pode ver um filme no Bagdad por 2 pilas. A quantos
130 | filmes você pode assistir lá? #{code '9/2'}... #{output '4'} filmes.
131 | 4.5 não é a resposta certa neste caso; eles não vão deixar
132 | você ver metade de um filme, ou metade de você ver um filme inteiro...
133 | algumas coisas não são divisíveis.
134 | END_PARAGRAPH
135 | end
136 | para do <<-END_PARAGRAPH
137 | Agora experimente com alguns programas seus! Se você quiser
138 | escrever expressões mais complexas, você pode usar parênteses.
139 | Por exemplo:
140 | END_PARAGRAPH
141 | end
142 | prog do <<-END_CODE
143 | puts 5 * (12-8) + -15
144 | puts 98 + (59872 / (13*8)) * -52
145 | END_CODE
146 | end
147 | h2 {'Umas Coisinhas Para Tentar'}
148 | para do
149 | puts 'Escreva um programa que lhe dê:'
150 | end
151 | ul do
152 | li {'quantas horas há em um ano?'}
153 | li {'quantos minutos há em uma década?'}
154 | li {'qual é a sua idade em segundos?'}
155 | li {'quantos chocolates você pretende comer na vida?
'+
156 | 'Aviso: Esta parte do programa pode demorar um pouco para computar!'}
157 | end
158 | para do
159 | puts "Eis uma pergunta mais difícil:"
160 | end
161 | ul do
162 | li {"Se minha idade é de #{(Time.now - Time.mktime(1976,8,3)).to_i / 1000000} milhões de segundos, qual é minha idade em anos?"}
163 | end
164 | para do <<-END_PARAGRAPH
165 | Quando você cansar de brincar com números, vamos dar uma
166 | olhada em algumas #{makeLink('letras', :generateLetters)}.
167 | END_PARAGRAPH
168 | end
169 | end
170 | end
171 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/setup.rb:
--------------------------------------------------------------------------------
1 | module Setup
2 | #
3 | # SETUP
4 | #
5 |
6 | def generateSetup
7 | para do <<-END_PARAGRAPH
8 | Quando você programa um computador, você tem que "falar" em
9 | uma língua que o seu computador entenda: uma linguagem de
10 | programação. Existem muitas e muitas linguagens por aí, e muitas
11 | são excelentes. Neste tutorial eu escolhi usar a minha favorita,
12 | Ruby.
13 | END_PARAGRAPH
14 | end
15 | #para do <<-END_PARAGRAPH
16 | # When you program a computer, you have to "speak" in a
17 | # language your computer understands: a programming
18 | # language. There are lots and lots of different
19 | # languages out there, and many of them are excellent.
20 | # In this tutorial I chose to use my favorite
21 | # programming language, Ruby.
22 | # END_PARAGRAPH
23 | #end
24 | para do <<-END_PARAGRAPH
25 | Além de ser a minha favorita, Ruby também é a linguagem mais
26 | fácil que eu já vi (e eu já vi uma boa quantidade delas). Aliás,
27 | esta é a verdadeira razão pela qual estou escrevendo este tutorial:
28 | Eu não decidi escrever este tutorial e aí escolhi Ruby por ser minha
29 | favorita; ao invés disso, eu descobri que o Ruby era tão fácil que
30 | eu decidi que deveria haver um bom tutorial que a usasse voltado
31 | para iniciantes.
32 | Foi a simplicidade do Ruby que inspirou este tutorial, não o fato
33 | dela ser minha favorita.
34 | (Escrever um tutorial similar usando outra linguagem, C++ ou Java, teria
35 | tomado centenas e centenas de páginas.) Mas não pense que Ruby é
36 | uma linguagem para iniciantes só porque é fácil! Ela é uma linguagem
37 | poderosa, de nível profissional como poucas.
38 | END_PARAGRAPH
39 | end
40 | #para do <<-END_PARAGRAPH
41 | # Aside from being my favorite,
42 | # Ruby is also the easiest programming language I have seen
43 | # (and I've seen quite a few). In fact, that's the real
44 | # reason I'm writing this tutorial: I didn't decide to write
45 | # a tutorial, and then choose Ruby because it's my favorite;
46 | # instead, I found Ruby to be so easy that I decided there
47 | # really ought to be a good beginner's tutorial which uses
48 | # it. It's Ruby's simplicity which prompted this tutorial,
49 | # not the fact that it's my favorite.
50 | # (Writing a similar tutorial using
51 | # another language, like C++ or Java, would have required
52 | # hundreds and hundreds of pages.) But don't think that
53 | # Ruby is a beginner's language just because it is easy!
54 | # It is a powerful, professional-strength programming
55 | # language if ever there was one.
56 | # END_PARAGRAPH
57 | #end
58 | para do <<-END_PARAGRAPH
59 | Quando você escreve algo em uma linguagem humana, o que é escrito
60 | é chamado de texto. Quando você escreve algo em uma linguagem de
61 | computador, o que é escrito é chamado de código. Eu incluí
62 | vários exemplos de código Ruby por todo este tutorial, a maioria
63 | deles programas completos que você pode rodar no seu próprio
64 | computador. Para deixar o código mais legível, eu colori partes dele
65 | com cores diferentes. (Por exemplo, números estão sempre em
66 | #{NUMBER_COLOR}.)
67 | Qualquer coisa que você tiver que digitar estará sempre numa
68 | #{input INPUT_DESC}, e qualquer coisa que o programa imprimir
69 | estará em uma #{output OUTPUT_DESC}.
70 | END_PARAGRAPH
71 | end
72 | #para do <<-END_PARAGRAPH
73 | # When you write something in a human language, what is
74 | # written is called text. When you write something in a computer
75 | # language, what is written is called code. I
76 | # have included lots of examples of Ruby code throughout
77 | # this tutorial, most of them complete programs you can
78 | # run on your own computer. To make the code easier to
79 | # read, I have colored parts of the code different
80 | # colors. (For example, numbers are always
81 | # #{NUMBER_COLOR}.)
82 | # Anything you are supposed to type in will be in a
83 | # #{input INPUT_DESC}, and anything a program prints
84 | # out will be in a #{output OUTPUT_DESC}.
85 | # END_PARAGRAPH
86 | #end
87 | para do <<-END_PARAGRAPH
88 | Se você encontrar algo que não entende, ou se você tiver
89 | uma pergunta que não foi respondida, tome nota e continue a ler!
90 | É bem possível que a resposta venha em um capítulo mais adiante.
91 | Porém, se sua pergunta não for respondida até o último
92 | capítulo, eu lhe mostrarei onde você pode ir para perguntar.
93 | Existem muitas pessoas maravilhosas por aí mais que dispostas a
94 | ajudar; você só precisa saber onde elas estão.
95 | END_PARAGRAPH
96 | end
97 | #para do <<-END_PARAGRAPH
98 | # If you come across something you don't understand, or you
99 | # have a question which wasn't answered, write it down and
100 | # keep reading! It's quite possible that the answer will
101 | # come in a later chapter. However, if your question was
102 | # not answered by the last chapter, I will tell you where
103 | # you can go to ask it. There are lots of wonderful people
104 | # out there more than willing to help; you just need to know
105 | # where they are.
106 | # END_PARAGRAPH
107 | #end
108 | para do <<-END_PARAGRAPH
109 | Mas primeiro nós precisamos baixar e instalar o Ruby no nosso
110 | computador.
111 | END_PARAGRAPH
112 | end
113 | h2 {'Instalação no Windows'}
114 | para do <<-END_PARAGRAPH
115 | A instalação do Ruby no Windows é muito fácil. Primeiro, você
116 | precisa baixar o
117 | Instalador Ruby.
118 | Pode haver mais de versão para escolher; este tutorial
119 | usa a versão #{RUBY_VERSION}, então assegure-se de que o que você
120 | baixar seja ao menos tão recente quanto ela. (Eu pegaria a última versão
121 | disponível.) Então simplesmente rode o programa de instalação.
122 | Ele perguntará onde você gostaria de instalar o Ruby. A não ser que
123 | você tenha uma boa razão para não fazer isso, eu instalaria no lugar
124 | recomendado.
125 | END_PARAGRAPH
126 | end
127 | #h2 {'Windows Installation'}
128 | #para do <<-END_PARAGRAPH
129 | # The Windows installation of Ruby is a breeze. First, you
130 | # need to download the
131 | # Ruby installer.
132 | # There might be a couple of versions to choose from; this tutorial
133 | # is using version #{RUBY_VERSION}, so make sure what you download is at
134 | # least as recent as that. (I would just get the latest
135 | # version available.) Then simply run the installation program.
136 | # It will ask you where you want to install Ruby. Unless you have
137 | # a good reason for it, I would just install it in the default
138 | # location.
139 | # END_PARAGRAPH
140 | #end
141 | para do <<-END_PARAGRAPH
142 | Para programar, você precisa poder escrever programas e rodá-los.
143 | Para fazer isso, você vai precisar de um editor de texto e uma
144 | linha de comando.
145 | END_PARAGRAPH
146 | end ## linha de comando?
147 |
148 | #para do <<-END_PARAGRAPH
149 | #In order to program, you need to be able to write programs and
150 | #to run programs. To do this, you will need a text editor and a
151 | #command line.
152 | #END_PARAGRAPH
153 | #end
154 | para do <<-END_PARAGRAPH
155 | O instalador do Ruby vem com um editor de texto adorável chamado
156 | SciTE (the Scintilla Text Editor). Você pode rodar o SciTE
157 | selecionando-o no menu Iniciar. Se você quiser que o seu código
158 | seja colorido como os exemplos deste tutorial, baixe estes arquivos
159 | e coloque-os na sua pasta SciTE (c:/ruby/scite se você escolher
160 | o local recomendado).
161 | END_PARAGRAPH
162 | end
163 | #para do <<-END_PARAGRAPH
164 | # The Ruby installer comes with a lovely text editor called SciTE
165 | # (the Scintilla Text Editor). You can run SciTE by selecting it
166 | # from the start menu. If you would like your code to be colored
167 | # like the examples in this tutorial, download these files and
168 | # put them in your SciTE folder (c:/ruby/scite if you chose the
169 | # default location):
170 | # END_PARAGRAPH
171 | #end
172 | ul do
173 | li {'Propriedades Globais'}
174 | li {'Propriedades do Ruby'}
175 | end
176 | para do <<-END_PARAGRAPH
177 | Seria também uma boa idéia criar um diretório em algum lugar para manter
178 | todos os seus programas. Tenha certeza que, quando você salvar um
179 | programa, esteja salvando neste diretório.
180 | END_PARAGRAPH
181 | end
182 | para do <<-END_PARAGRAPH
183 | Para ir para sua linha de comando, selecione Prompt de Comando na pasta
184 | Acessórios do seu menu Iniciar. Você vai querer
185 | navegar para o diretório onde você mantém seus programas.
186 | Digitar #{input 'cd ..'} levará você para o diretório anterior, e
187 | #{input 'cd nome_do_diretorio'} colocará você dentro do diretório
188 | chamado nome_do_diretorio. Para ver todos seus diretórios
189 | dentro do diretório atual, digite #{input 'dir /ad'}.
190 | END_PARAGRAPH
191 | end
192 | para do <<-END_PARAGRAPH
193 | E é isto! Você está pronto para
194 | #{makeLink 'aprender a programar', :generateNumbers}.
195 | END_PARAGRAPH
196 | end
197 | h2 {'Instalação para Macintosh'}
198 | para do <<-END_PARAGRAPH
199 | Se você tiver um Mac OS X 10.2 (Jaguar), então você já tem
200 | Ruby no seu sistema! O que poderia ser mais fácil?
201 | Infelizmente, eu não acho que você possa usar Ruby no Mac OS X 10.1
202 | e versões anteriores.
203 | END_PARAGRAPH
204 | end
205 | para do <<-END_PARAGRAPH
206 | Para programar, você precisa ser capaz de escrever programas e
207 | executá-los. Para fazer isto, você precisará de um editor de textos e
208 | uma linha de comando.
209 | END_PARAGRAPH
210 | end
211 | para do <<-END_PARAGRAPH
212 | Sua linha de comando está acessível através da aplicação
213 | Terminal (encontrada em Aplicações/Utilitários).
214 | END_PARAGRAPH
215 | end
216 | para do <<-END_PARAGRAPH
217 | Para um editor de textos, você pode usar qualquer um com que você
218 | esteja familiarizado ou se sinta confortável usando.
219 | Se você usa TextEdit, entretanto, tenha certeza
220 | que você está salvando seus programas como somente-texto! Caso contrário seus programas
221 | não funcionarão. Outras opções para programar são
222 | emacs, vi, e pico, que estão todos acessíveis via
223 | linha de comando.
224 | END_PARAGRAPH
225 | end
226 | para do <<-END_PARAGRAPH
227 | E é isto! Você está pronto para
228 | #{makeLink 'aprender a programar', :generateNumbers}.
229 | END_PARAGRAPH
230 | end
231 | h2 {'Instalação em Linux'}
232 | para do <<-END_PARAGRAPH
233 | Primeiro, vale a pena checar se você já tem Ruby
234 | instalado. Digite #{input 'which ruby'}. Se este comando responder
235 | algo como #{output '/usr/bin/which: no ruby in (...)'}, então você precisa
236 | fazer o download do Ruby,
237 | caso contrário veja que versão do Ruby você possui com
238 | #{input 'ruby -v'}. Se for mais velha do que a última versão estável
239 | na página de download acima, pode ser bom atualizá-lo.
240 | END_PARAGRAPH
241 | end
242 | para do <<-END_PARAGRAPH
243 | Se você for o usuário root, então você provavelmente não precisa de
244 | qualquer instrução para instalar o Ruby. Se não for, você poderia
245 | pedir ao seu administrador de sistema para instalá-lo para você.
246 | (Desta forma todos neste sistema poderiam usar Ruby.)
247 | END_PARAGRAPH
248 | end
249 | para do <<-END_PARAGRAPH
250 | Caso contrário, você pode apenas instalá-lo de forma que apenas
251 | você possa usá-lo.
252 | Mova o arquivo baixado para um diretório temporário, como
253 | $HOME/tmp. Se o nome do arquivo for
254 | ruby-1.6.7.tar.gz, você pode abri-lo com
255 | #{input 'tar zxvf ruby-1.6.7.tar.gz'}. Mude do diretório atual
256 | para o diretório que acabou de ser criado (neste exemplo,
257 | #{input 'cd ruby-1.6.7'}).
258 | END_PARAGRAPH
259 | end
260 | para do <<-END_PARAGRAPH
261 | Configure sua instalação digitando
262 | #{input './configure --prefix=$HOME'}). Depois digite
263 | #{input 'make'}, que construirá seu interpretador Ruby.
264 | Isto pode levar alguns minutos. Após isto ter terminado, digite
265 | #{input 'make install'} para instalá-lo.
266 | END_PARAGRAPH
267 | end
268 | para do <<-END_PARAGRAPH
269 | Em seguida, você vai querer adicionar $HOME/bin para seu
270 | caminho de busca de comandos à variável de ambiente PATH, editando
271 | seu arquivo $HOME/.bashrc.
272 | (Você pode ter que se deslogar e logar novamente para que
273 | isto surta efeito.) Após ter feito isto, teste sua instalação:
274 | #{input 'ruby -v'}. Se mostrar a você qual a versão do Ruby que você
275 | tem, você pode agora remover os arquivos
276 | em $HOME/tmp (ou onde quer que você os colocou).
277 | END_PARAGRAPH
278 | end
279 | para do <<-END_PARAGRAPH
280 | E é isto! Você está pronto para
281 | #{makeLink 'aprender a programar', :generateNumbers}.
282 | END_PARAGRAPH
283 | end
284 | end
285 | end
286 |
--------------------------------------------------------------------------------
/lib/learn_to_program_tutorial/variables.rb:
--------------------------------------------------------------------------------
1 | module Variables
2 | #
3 | # VARIABLES
4 | #
5 |
6 | def generateVariables
7 | para do <<-END_PARAGRAPH
8 | Até agora, sempre que usamos #{code 'puts'} numa string ou número,
9 | o que imprimimos some. O que eu quero dizer é, se quiséssemos imprimir
10 | algo duas vezes, teríamos que digitar duas vezes:
11 | END_PARAGRAPH
12 | end
13 | prog do <<-END_CODE
14 | puts '...você pode dizer aquilo de novo...'
15 | puts '...você pode dizer aquilo de novo...'
16 | END_CODE
17 | end
18 | para do <<-END_PARAGRAPH
19 | Seria legal se pudéssemos digitá-lo uma única vez e mantê-lo por perto...
20 | guardá-lo em algum lugar.
21 | Bom, nós podemos, é claro—caso contrário eu não teria tocado no assunto!
22 | END_PARAGRAPH
23 | end
24 | para do <<-END_PARAGRAPH
25 | Para guardar a string na memória de seu computador, precisamos dar
26 | um nome a ela. Normalmente os programadores chamam esse processo de
27 | atribuição, e chamam os nomes de variáveis. A
28 | variável pode ser praticamente qualquer seqüência de letras e números,
29 | mas o primeiro caracter tem de ser uma letra minúscula. Vamos rodar
30 | o último programa de novo, mas desta vez eu darei à string o nome de
31 | #{code 'minhaString'} (ainda que eu pudesse tê-la chamado de
32 | #{code 'str'} ou #{code 'minhaStringzinha'} ou #{code 'pedroPrimeiro'}).
33 | END_PARAGRAPH
34 | end
35 | prog do <<-END_CODE
36 | minhaString = '...você pode dizer aquilo de novo...'
37 | puts minhaString
38 | puts minhaString
39 | END_CODE
40 | end
41 | para do <<-END_PARAGRAPH
42 | Sempre que você tentou fazer algo com #{code 'minhaString'}, o programa
43 | fez com #{code "'...você pode dizer aquilo de novo'"} no lugar. Você
44 | pode pensar na variável #{code 'minhaString'} como "apontando para" a
45 | string #{code "'...você pode dizer aquilo de novo...'"}. Eis um exemplo
46 | um pouquinho mais interessante:
47 | END_PARAGRAPH
48 | end
49 | prog do <<-END_CODE
50 | nome = 'Patricia Rosanna Jessica Mildred Oppenheimer'
51 | puts 'Meu nome é ' + nome + '.'
52 | puts 'Nossa! ' + nome + ' é um nome bem longo!'
53 | END_CODE
54 | end
55 | para do <<-END_PARAGRAPH
56 | Assim como podemos atribuir um objeto a uma variável,
57 | podemos reatribuir um objeto diferente à mesma variável (e
58 | é por isso que nós as chamamos de variáveis: porque a coisa para
59 | a qual apontam pode variar).
60 | END_PARAGRAPH
61 | end
62 | prog do <<-END_CODE
63 | compositor = 'Mozart'
64 | puts compositor + ' era "sensa", na sua época.'
65 |
66 | compositor = 'Beethoven'
67 | puts 'Mas eu, pessoalmente, prefiro ' + compositor + '.'
68 | END_CODE
69 | end
70 | para do <<-END_PARAGRAPH
71 | Variáveis podem, é claro, apontar para qualquer tipo de objeto, não
72 | só strings:
73 | END_PARAGRAPH
74 | end
75 | prog do <<-END_CODE
76 | var = 'só mais uma ' + 'string'
77 | puts var
78 |
79 | var = 5 * (1+2)
80 | puts var
81 | END_CODE
82 | end
83 | para do <<-END_PARAGRAPH
84 | Na verdade, variáveis podem apontar para qualquer coisa...
85 | que não outras variáveis.
86 | Então o que acontece se tentarmos?
87 | END_PARAGRAPH
88 | end
89 | prog do <<-END_CODE
90 | var1 = 8
91 | var2 = var1
92 | puts var1
93 | puts var2
94 |
95 | puts ''
96 |
97 | var1 = 'oito'
98 | puts var1
99 | puts var2
100 | END_CODE
101 | end
102 | para do <<-END_PARAGRAPH
103 | Primeiro, quando tentamos apontar #{code 'var2'} para #{code 'var1'},
104 | #{code 'var2'} apontou para #{code '8'} (exatamente como #{code 'var1'}
105 | apontava). Aí fizemos #{code 'var1'} apontar para #{code "'oito'"}, mas
106 | como #{code 'var2'} nunca apontou de verdade para #{code 'var1'}, ela
107 | se mantém apontando para #{code '8'}.
108 | END_PARAGRAPH
109 | end
110 | para do <<-END_PARAGRAPH
111 | Agora que temos variáveis, números e strings, vamos aprender como
112 | #{makeLink 'misturar todos eles', :generateConversion}!
113 | END_PARAGRAPH
114 | end
115 | end
116 | end
117 |
--------------------------------------------------------------------------------
/log/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/log/.gitignore
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 | # General Apache options
2 | AddHandler fastcgi-script .fcgi
3 | AddHandler cgi-script .cgi
4 | Options +FollowSymLinks +ExecCGI
5 |
6 | # If you don't want Rails to look in certain directories,
7 | # use the following rewrite rules so that Apache won't rewrite certain requests
8 | #
9 | # Example:
10 | # RewriteCond %{REQUEST_URI} ^/notrails.*
11 | # RewriteRule .* - [L]
12 |
13 | # Redirect all requests not available on the filesystem to Rails
14 | # By default the cgi dispatcher is used which is very slow
15 | #
16 | # For better performance replace the dispatcher with the fastcgi one
17 | #
18 | # Example:
19 | # RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
20 | RewriteEngine On
21 |
22 | # If your Rails application is accessed via an Alias directive,
23 | # then you MUST also set the RewriteBase in this htaccess file.
24 | #
25 | # Example:
26 | # Alias /myrailsapp /path/to/myrailsapp/public
27 | # RewriteBase /myrailsapp
28 |
29 | RewriteRule ^$ index.html [QSA]
30 | RewriteRule ^([^.]+)$ $1.html [QSA]
31 | RewriteCond %{REQUEST_FILENAME} !-f
32 | RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
33 |
34 | # In case Rails experiences terminal errors
35 | # Instead of displaying this message you can supply a file here which will be rendered instead
36 | #
37 | # Example:
38 | # ErrorDocument 500 /500.html
39 |
40 | ErrorDocument 500 "Application error
Rails application failed to start properly"
41 |
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | The page you were looking for doesn't exist (404)
9 |
21 |
22 |
23 |
24 |
25 |
26 |
The page you were looking for doesn't exist.
27 |
You may have mistyped the address or the page may have moved.
28 |
29 |
30 |
--------------------------------------------------------------------------------
/public/422.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | The change you wanted was rejected (422)
9 |
21 |
22 |
23 |
24 |
25 |
26 |
The change you wanted was rejected.
27 |
Maybe you tried to change something you didn't have access to.
28 |
29 |
30 |
--------------------------------------------------------------------------------
/public/500.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | We're sorry, but something went wrong (500)
9 |
21 |
22 |
23 |
24 |
25 |
26 |
We're sorry, but something went wrong.
27 |
We've been notified about this issue and we'll take a look at it shortly.
28 |
29 |
30 |
--------------------------------------------------------------------------------
/public/SciTEGlobal.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/SciTEGlobal.properties
--------------------------------------------------------------------------------
/public/dispatch.cgi:
--------------------------------------------------------------------------------
1 | #!/opt/local/bin/ruby
2 |
3 | require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
4 |
5 | # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
6 | # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
7 | require "dispatcher"
8 |
9 | ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
10 | Dispatcher.dispatch
--------------------------------------------------------------------------------
/public/dispatch.fcgi:
--------------------------------------------------------------------------------
1 | #!/opt/local/bin/ruby
2 | #
3 | # You may specify the path to the FastCGI crash log (a log of unhandled
4 | # exceptions which forced the FastCGI instance to exit, great for debugging)
5 | # and the number of requests to process before running garbage collection.
6 | #
7 | # By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
8 | # and the GC period is nil (turned off). A reasonable number of requests
9 | # could range from 10-100 depending on the memory footprint of your app.
10 | #
11 | # Example:
12 | # # Default log path, normal GC behavior.
13 | # RailsFCGIHandler.process!
14 | #
15 | # # Default log path, 50 requests between GC.
16 | # RailsFCGIHandler.process! nil, 50
17 | #
18 | # # Custom log path, normal GC behavior.
19 | # RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
20 | #
21 | require File.dirname(__FILE__) + "/../config/environment"
22 | require 'fcgi_handler'
23 |
24 | RailsFCGIHandler.process!
25 |
--------------------------------------------------------------------------------
/public/dispatch.rb:
--------------------------------------------------------------------------------
1 | #!/opt/local/bin/ruby
2 |
3 | require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
4 |
5 | # If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
6 | # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
7 | require "dispatcher"
8 |
9 | ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
10 | Dispatcher.dispatch
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/favicon.ico
--------------------------------------------------------------------------------
/public/images/LTP_cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/LTP_cover.jpg
--------------------------------------------------------------------------------
/public/images/PoweredByRuby.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/PoweredByRuby.png
--------------------------------------------------------------------------------
/public/images/fleur_right.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/fleur_right.gif
--------------------------------------------------------------------------------
/public/images/flowerborder.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/flowerborder.gif
--------------------------------------------------------------------------------
/public/images/locketLTP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/locketLTP.png
--------------------------------------------------------------------------------
/public/images/paper_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/paper_background.png
--------------------------------------------------------------------------------
/public/images/rails.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/rails.png
--------------------------------------------------------------------------------
/public/images/shadowS.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/shadowS.gif
--------------------------------------------------------------------------------
/public/images/speardown_sm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/speardown_sm.gif
--------------------------------------------------------------------------------
/public/images/spearup_sm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/spearup_sm.gif
--------------------------------------------------------------------------------
/public/images/swirly.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/swirly.gif
--------------------------------------------------------------------------------
/public/images/titleLTP.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/titleLTP.gif
--------------------------------------------------------------------------------
/public/images/titleLTP_pt_br.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmonteiro/aprendaaprogramar/961a7d32d91480c4e2f4be3b8621c74ec21abf00/public/images/titleLTP_pt_br.gif
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-Agent: *
5 | # Disallow: /
6 |
--------------------------------------------------------------------------------
/public/ruby.properties:
--------------------------------------------------------------------------------
1 | # Define SciTE settings for Ruby files.
2 |
3 | file.patterns.rb=*.rb;*.rbw;*.rbx
4 |
5 | filter.ruby=Ruby (rb rbw rbx)|$(file.patterns.rb)|
6 |
7 | lexer.$(file.patterns.rb)=ruby
8 |
9 | keywordclass.ruby=__FILE__ and def end in or self unless __LINE__ begin \
10 | defined? ensure module redo super until BEGIN break do false next rescue \
11 | then when END case else for nil retry true while alias class elsif if \
12 | not return undef yield
13 | keywords.$(file.patterns.rb)=$(keywordclass.ruby)
14 |
15 | statement.indent.*.rb=
16 | statement.end*.rb=
17 | statement.lookback.*.rb=1
18 | block.start.*.rb=10
19 |
20 | comment.block.ruby=#~
21 |
22 | # ruby styles
23 | # White space
24 | style.ruby.0=fore:#0000FF
25 | # Comment
26 | style.ruby.1=fore:#FFFFFF,$(font.comment)
27 | # Number
28 | style.ruby.2=fore:#007F00
29 | # String
30 | style.ruby.3=fore:#C00000,$(font.monospace)
31 | # Single quoted string
32 | style.ruby.4=fore:#C00000,$(font.monospace)
33 | # Keyword
34 | style.ruby.5=fore:#0000FF
35 | # Triple quotes
36 | style.ruby.6=fore:#FFFFFF
37 | # Triple double quotes
38 | style.ruby.7=fore:#FFFFFF
39 | # Class name definition
40 | style.ruby.8=fore:#7F007F
41 | # Function or method name definition
42 | style.ruby.9=fore:#7F007F
43 | # Operators
44 | #style.ruby.10=bold
45 | # Identifiers
46 | style.ruby.11=fore:#000000
47 | # Comment-blocks
48 | style.ruby.12=fore:#FFFFFF
49 | # End of line where string is not closed
50 | style.ruby.13=fore:#000000,$(font.monospace),back:#E0C0E0,eolfilled
51 | # Matched Operators
52 | #style.ruby.34=fore:bold
53 | #style.ruby.35=fore:#FF0000
54 | # Braces are only matched in operator style
55 | braces.ruby.style=10
56 |
57 | if PLAT_WIN
58 | command.go.*.rb=ruby $(FileNameExt)
59 | command.go.subsystem.*.rb=1
60 |
61 | if PLAT_GTK
62 | command.go.*.rb=ruby $(FileNameExt)
63 |
--------------------------------------------------------------------------------
/public/stylesheets/pine.css:
--------------------------------------------------------------------------------
1 | body
2 | {
3 | color: #403b31;
4 | background: #f6f4e3 url(../images/paper_background.png);
5 | }
6 |
7 | *
8 | {
9 | margin: 0px;
10 | padding: 0px;
11 | border: 0px;
12 | }
13 |
14 | body, p, ol, ul, td
15 | {
16 | /*font-family: verdana, arial, helvetica, sans-serif;*/
17 | font-family: palatino, bookman, "Bookman Old Style", "Book Antiqua", serif;
18 | font-size: 15px;
19 | /*line-height: 18px;*/
20 | }
21 |
22 |
23 | blockquote
24 | {
25 | padding: 5px;
26 | padding-left: 0px;
27 | margin: 7px;
28 | margin-left: 17px;
29 | font-size: 12px;
30 | font-style: italic;
31 | /*border-left: 2px solid #db9;*/
32 | }
33 | blockquote em { font-style: normal; }
34 | blockquote p { font-size: 12px; }
35 |
36 |
37 | p, ol, ul { padding: 5px; }
38 | img { display: block; }
39 |
40 | a { color: #3a4; }
41 | a:visited { color: #807b71; }
42 | a:hover { color: #3b4; /*background-color:#000;*/ }
43 |
44 | acronym { border-bottom: 1px dotted black; }
45 |
46 | .domhidden { display: none; }
47 |
48 | #debugModeWarning
49 | {
50 | position: fixed;
51 | top: 35px;
52 | left: 30px;
53 | z-index: 5;
54 | }
55 |
56 | #debugModeWarningInnerDiv
57 | {
58 | font-size: 20px;
59 | font-family: vinque, dungeon;
60 | color: #a00;
61 | }
62 |
63 | #pageWidth
64 | {
65 | width: 100%;
66 | min-width: 500px;
67 | }
68 |
69 | #locket
70 | {
71 | position: absolute;
72 | top: 15px;
73 | right: 15px;
74 | }
75 |
76 | #headerBar
77 | {
78 | height:122px;
79 | width:100%;
80 | position: absolute;
81 | top: 0px;
82 | left: 0px;
83 | background: #403b31 url(../images/flowerborder.gif) bottom repeat-x;
84 | }
85 |
86 | #titlePicContainer
87 | {
88 | position: relative;
89 | left: 50%;
90 | width: 50%;
91 | }
92 | #titlePic
93 | {
94 | position: relative;
95 | top: 2px;
96 | left: -258px;
97 | /*color: #d8c0a0;*/
98 | }
99 |
100 | #menuPane
101 | {
102 | position: absolute;
103 | top: 150px;
104 | width: 190px;
105 | left: 25px;
106 | padding: 8px;
107 | }
108 |
109 | #menuPane img
110 | {
111 | margin-left: auto;
112 | margin-right: auto;
113 | position: relative;
114 | left: -10px;
115 | }
116 |
117 | #menuPane a { text-decoration: none; font-weight: bold; }
118 | #menuPane a:visited { color: #3a4; font-weight: bold; }
119 | #menuPane a:hover { color: #3b4; text-decoration: underline; font-weight: bold; }
120 |
121 | #menuPane a.stealth_link { color: #403b31; font-weight: normal; }
122 | #menuPane a.stealth_link:visited { color: #403b31; }
123 | #menuPane a.stealth_link:hover { color: #3b4; }
124 |
125 | #menuSpearTop
126 | {
127 | padding-bottom: 30px; /* space between spear and menu content */
128 | }
129 |
130 | #menuSpearBottom
131 | {
132 | top: 30px; /* space between spear and menu content */
133 | }
134 |
135 | #menuPane p, ul, ol
136 | {
137 | /*letter-spacing: 1px;*/
138 | font-size: 10px;
139 | font-family: verdana, tahoma, helvetica, arial, sans-serif;
140 | line-height: 1.3;
141 | }
142 |
143 | .funnyMenuText
144 | {
145 | text-align: center;
146 | position: relative;
147 | left: -12px;
148 | }
149 |
150 | #contentPane
151 | {
152 | position: absolute;
153 | top: 160px;
154 | left: 260px;
155 | right: 40px;
156 | }
157 |
158 | #contentPane p
159 | {
160 | line-height: 120%;
161 | clear: both;
162 | padding-left: 15px;
163 | }
164 |
165 | .blogview
166 | {
167 | margin: 5px;
168 | clear: both;
169 | }
170 |
171 | .latest_comment_date
172 | {
173 | font-size: 14px;
174 | line-height: 100%;
175 | font-style: italic;
176 | clear: both;
177 | color: #706645;
178 | padding-bottom: 24px;
179 | padding-top: 0px;
180 | padding-left: 40px;
181 | margin-top: -12px;
182 | }
183 |
184 | .picture_caption
185 | {
186 | font-size: 14px;
187 | line-height: 100%;
188 | font-style: italic;
189 | color: #706645;
190 | padding-left: 15px;
191 | padding-bottom: 5px;
192 | clear: both;
193 | }
194 |
195 | .photo_caption
196 | {
197 | font-size: 14px;
198 | line-height: 100%;
199 | font-style: italic;
200 | color: #706645;
201 | }
202 |
203 | .fleur
204 | {
205 | clear: both;
206 | background: url(../images/fleur_right.gif) bottom right no-repeat;
207 | padding-bottom: 20px; /* Needs to be 20px for the fleur stem. */
208 | }
209 |
210 | .fleur_stem
211 | {
212 | padding-bottom: 10px; /* Controls blank space above the fleur. */
213 | margin-right: 30px; /* Needs to be 30px for the fleur stem. */
214 | border-bottom-width: 1px;
215 | border-style: solid;
216 | border-color: #706645;
217 | }
218 |
219 | .commenter
220 | {
221 | font-size: 17px;
222 | clear: both;
223 | color: #706645;
224 | padding: 5px;
225 | padding-left: 35px; /* Controls horizontal positioning of the name relative to dash (should be about 35px). */
226 | padding-bottom: 17px;
227 | margin-top: -22px;
228 | margin-left: 30px; /* Controls horizontal positioning of the name-dash combo. */
229 | /*content: "hootie"*/
230 | }
231 | /*.commenter::after
232 | {
233 | content: " said it"
234 | }*/
235 |
236 | .commenter img
237 | {
238 | display: inline;
239 | position: relative;
240 | top: 13px;
241 | }
242 |
243 | .name_header
244 | {
245 | font-size: 35px;
246 | letter-spacing: 2px;
247 | font-weight: bolder;
248 | font-style: italic;
249 | color: #706645;
250 | padding-left: 50px;
251 | }
252 |
253 | h1
254 | {
255 | font-size: 25px;
256 | text-align: center;
257 | letter-spacing: 2px;
258 | font-variant: small-caps;
259 | font-weight: bolder;
260 | color: #706645;
261 | margin-bottom: 20px;
262 | padding-top: 20px; /* Controls blank space below the fleur. */
263 | }
264 |
265 | h2
266 | {
267 | font-size: 20px;
268 | letter-spacing: 2px;
269 | font-variant: small-caps;
270 | font-weight: bolder;
271 | color: #706645;
272 | margin-bottom: 20px;
273 | padding-top: 20px; /* Controls blank space below the fleur. */
274 | padding-left: 20px;
275 | }
276 |
277 | h3
278 | {
279 | position: relative;
280 | left: 10px;
281 | padding: 15px;
282 | }
283 |
284 | .shadow_corner
285 | {
286 | z-index: 1;
287 | width: 7px;
288 | position: absolute;
289 | }
290 |
291 | .shadow_nw
292 | {
293 | height: 6px;
294 | }
295 |
296 | .shadow_ne
297 | {
298 | height: 6px;
299 | right: 0px;
300 | }
301 |
302 | .shadow_sw
303 | {
304 | height: 8px;
305 | bottom: 0px;
306 | }
307 |
308 | .shadow_se
309 | {
310 | height: 8px;
311 | right: 0px;
312 | bottom: 0px;
313 | }
314 |
315 | .photo
316 | {
317 | z-index: -1;
318 | padding: 5px 5px 8px 5px;
319 | background: #ffffff url(../images/shadowS.gif) repeat-x bottom left;
320 | }
321 |
322 | .photo_and_shadow
323 | {
324 | margin: 5px;
325 | float: left;
326 | position: relative;
327 | }
328 |
329 | .shadow_edges
330 | {
331 | background: #abaa9e;
332 | padding: 0px 1px 0px 1px;
333 | border: 1px solid #dfddce;
334 | border-bottom: 0px;
335 | }
336 |
337 | .form_text_field
338 | {
339 | background: #f9f8f0;
340 | padding: .25em;
341 | margin: .15em;
342 | border: 1px solid #a3895c;
343 | }
344 |
345 | .form_drop_down
346 | {
347 | background: #f9f8f0;
348 | border: 1px solid #a3895c;
349 | }
350 |
351 | .form_text_area
352 | {
353 | background: #f9f8f0;
354 | border: 1px solid #a3895c;
355 | padding: .25em;
356 | }
357 |
358 | .formatting_tips
359 | {
360 | float: left;
361 | margin-left: 30px;
362 | }
363 |
364 | .button
365 | {
366 | border: 3px double #999999;
367 | border-top-color: #CCCCCC;
368 | border-left-color: #CCCCCC;
369 | padding: 0.15em;
370 | margin: 5px 0px 5px 20px;
371 | background-color: #f9f8f0;
372 | color: #403b31;
373 | font-size: 75%;
374 | font-weight: bold;
375 | font-family: palatino, bookman, "Bookman Old Style", "Book Antiqua", serif;
376 | }
377 |
378 | /***********************************
379 | ******** Rails Stuff below ********
380 | ***********************************/
381 |
382 | .fieldWithErrors {
383 | padding: 2px;
384 | background-color: red;
385 | display: table;
386 | }
387 |
388 | #ErrorExplanation {
389 | width: 400px;
390 | border: 2px solid red;
391 | padding: 7px;
392 | padding-bottom: 12px;
393 | margin-bottom: 20px;
394 | background-color: #f0f0f0;
395 | }
396 |
397 | #ErrorExplanation h2 {
398 | text-align: left;
399 | font-weight: bold;
400 | padding: 5px 5px 5px 15px;
401 | font-size: 12px;
402 | margin: -7px;
403 | background-color: #c00;
404 | color: #fff;
405 | }
406 |
407 | #ErrorExplanation p {
408 | color: #333;
409 | margin-bottom: 0;
410 | padding: 5px;
411 | }
412 |
413 | #ErrorExplanation ul li {
414 | font-size: 12px;
415 | list-style: square;
416 | }
417 |
418 | div.uploadStatus {
419 | margin: 5px;
420 | }
421 |
422 | div.progressBar {
423 | margin: 5px;
424 | }
425 |
426 | div.progressBar div.border {
427 | background-color: #fff;
428 | border: 1px solid grey;
429 | width: 100%;
430 | }
431 |
432 | div.progressBar div.background {
433 | background-color: #333;
434 | height: 18px;
435 | width: 0%;
436 | }
437 |
438 |
--------------------------------------------------------------------------------
/public/stylesheets/print.css:
--------------------------------------------------------------------------------
1 | #menuPane
2 | {
3 | display: none;
4 | }
5 | #titlePicContainer
6 | {
7 | position: relative;
8 | left: 50%;
9 | width: 50%;
10 | }
11 | #titlePicContainer a img {
12 | border: 0;
13 | }
14 | #titlePic
15 | {
16 | position: relative;
17 | top: 2px;
18 | left: -256px;
19 | /*color: #d8c0a0;*/
20 | }
21 | #locket
22 | {
23 | position: absolute;
24 | top: 15px;
25 | right: 15px;
26 | }
27 |
--------------------------------------------------------------------------------
/public/stylesheets/tutorial.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | #menuPane
4 | {
5 | position: absolute;
6 | top: 150px;
7 | width: 190px;
8 | left: 25px;
9 | padding: 8px;
10 | }
11 |
12 |
13 | #menuPane a { text-decoration: none; font-weight: normal; }
14 | #menuPane a:visited { color: #3a4; font-weight: normal; }
15 | #menuPane a:hover { color: #3b4; text-decoration: underline; font-weight: normal; }
16 |
17 |
18 | #menuPane p, ul, ol
19 | {
20 | font-size: 10px;
21 | font-family: verdana, tahoma, helvetica, arial, sans-serif;
22 | line-height: 1.3;
23 | }
24 |
25 | .funnyMenuText
26 | {
27 | text-align: center;
28 | position: relative;
29 | left: -10px;
30 | }
31 |
32 | .fancyMenuText
33 | {
34 | letter-spacing: 1px;
35 | padding: 0px;
36 | padding-bottom: 5px;
37 | margin-top: -5px;
38 | }
39 |
40 |
41 | h1
42 | {
43 | font-size: 25px;
44 | text-align: center;
45 | letter-spacing: 2px;
46 | font-variant: small-caps;
47 | font-weight: bolder;
48 | color: #706645;
49 | margin-bottom: 20px;
50 | padding-top: 20px; /* Controls blank space below the fleur. */
51 | }
52 |
53 | h2
54 | {
55 | font-size: 20px;
56 | letter-spacing: 2px;
57 | font-variant: small-caps;
58 | font-weight: bolder;
59 | color: #706645;
60 | margin-bottom: 20px;
61 | padding-top: 20px; /* Controls blank space below the fleur. */
62 | padding-left: 20px;
63 | }
64 |
65 | h3
66 | {
67 | position: relative;
68 | left: 10px;
69 | padding: 15px;
70 | }
71 |
72 |
73 | /***********************************
74 | ********** L2P Stuff below *********
75 | ***********************************/
76 |
77 | pre
78 | {
79 | padding: 10px;
80 | margin: 20px;
81 | width: 90%;
82 | }
83 |
84 | .L2Pinput
85 | {
86 | border-right: #d0b0b0 1px solid;
87 | border-top: #907070 1px solid;
88 | border-left: #705050 1px solid;
89 | border-bottom: #c0a0a0 1px solid;
90 | padding-right: 3px;
91 | padding-top: 0px;
92 | padding-left: 3px;
93 | padding-bottom: 0px;
94 | white-space: pre;
95 | font-family: courier new, monospace;
96 | background-color: #f3f4f6;
97 | }
98 |
99 | .L2Pcode
100 | {
101 | padding-right: 0px;
102 | padding-top: 0px;
103 | padding-left: 0px;
104 | padding-bottom: 0px;
105 | white-space: pre;
106 | font-family: courier new, monospace;
107 | font-weight: 600;
108 | }
109 |
110 | .L2PcodeBG
111 | {
112 | background-color: #c6d2e8;
113 | }
114 |
115 | .L2PcodeBlock
116 | {
117 | background-color: #d2cbbe;
118 | border-right: #fffbee 1px solid;
119 | border-top: #b2ab9e 1px solid;
120 | border-left: #a29b8e 1px solid;
121 | border-bottom: #f2ebde 1px solid;
122 | }
123 |
124 | .L2PoutputBlock
125 | {
126 | background-color: #c6d2e8;
127 | border-right: #909aba 1px solid;
128 | border-top: #d6e2ff 1px solid;
129 | border-left: #e3f2f4 1px solid;
130 | border-bottom: #a0aaca 1px solid;
131 | }
132 |
133 | .L2Pstring
134 | {
135 | color: #c00000;
136 | }
137 |
138 | .L2Pnumber
139 | {
140 | color: #007f00;
141 | }
142 |
143 | .L2Pkeyword
144 | {
145 | color: #0000ff;
146 | }
147 |
148 | .L2Pdefinition
149 | {
150 | color: #7f007f;
151 | }
152 |
153 | .L2Pcomment
154 | {
155 | color: #ffffff;
156 | }
157 |
158 |
--------------------------------------------------------------------------------
/script/about:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../config/boot'
3 | require 'commands/about'
4 |
--------------------------------------------------------------------------------
/script/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../config/boot'
3 | require 'commands/console'
4 |
--------------------------------------------------------------------------------
/script/destroy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../config/boot'
3 | require 'commands/destroy'
4 |
--------------------------------------------------------------------------------
/script/generate:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../config/boot'
3 | require 'commands/generate'
4 |
--------------------------------------------------------------------------------
/script/performance/benchmarker:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../../config/boot'
3 | require 'commands/performance/benchmarker'
4 |
--------------------------------------------------------------------------------
/script/performance/profiler:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../../config/boot'
3 | require 'commands/performance/profiler'
4 |
--------------------------------------------------------------------------------
/script/performance/request:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../../config/boot'
3 | require 'commands/performance/request'
4 |
--------------------------------------------------------------------------------
/script/plugin:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../config/boot'
3 | require 'commands/plugin'
4 |
--------------------------------------------------------------------------------
/script/process/inspector:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../../config/boot'
3 | require 'commands/process/inspector'
4 |
--------------------------------------------------------------------------------
/script/process/reaper:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../../config/boot'
3 | require 'commands/process/reaper'
4 |
--------------------------------------------------------------------------------
/script/process/spawner:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../../config/boot'
3 | require 'commands/process/spawner'
4 |
--------------------------------------------------------------------------------
/script/runner:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../config/boot'
3 | require 'commands/runner'
4 |
--------------------------------------------------------------------------------
/script/server:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../config/boot'
3 | require 'commands/server'
4 |
--------------------------------------------------------------------------------
/test/functional/learn_controller_test.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/../test_helper'
2 |
3 | class LearnControllerTest < ActionController::TestCase
4 | # Replace this with your real tests.
5 | def test_truth
6 | assert true
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | ENV["RAILS_ENV"] = "test"
2 | require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
3 | require 'test_help'
4 |
5 | class Test::Unit::TestCase
6 | # Transactional fixtures accelerate your tests by wrapping each test method
7 | # in a transaction that's rolled back on completion. This ensures that the
8 | # test database remains unchanged so your fixtures don't have to be reloaded
9 | # between every test method. Fewer database queries means faster tests.
10 | #
11 | # Read Mike Clark's excellent walkthrough at
12 | # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
13 | #
14 | # Every Active Record database supports transactions except MyISAM tables
15 | # in MySQL. Turn off transactional fixtures in this case; however, if you
16 | # don't care one way or the other, switching from MyISAM to InnoDB tables
17 | # is recommended.
18 | #
19 | # The only drawback to using transactional fixtures is when you actually
20 | # need to test transactions. Since your test is bracketed by a transaction,
21 | # any transactions started in your code will be automatically rolled back.
22 | self.use_transactional_fixtures = true
23 |
24 | # Instantiated fixtures are slow, but give you @david where otherwise you
25 | # would need people(:david). If you don't want to migrate your existing
26 | # test cases which use the @david style and don't mind the speed hit (each
27 | # instantiated fixtures translates to a database query per test method),
28 | # then set this back to true.
29 | self.use_instantiated_fixtures = false
30 |
31 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
32 | #
33 | # Note: You'll currently still have to declare fixtures explicitly in integration tests
34 | # -- they do not yet inherit this setting
35 | fixtures :all
36 |
37 | # Add more helper methods to be used by all tests here...
38 | end
39 |
--------------------------------------------------------------------------------