% Copyright (c)  2007 Rémi Laurent <remi.laurent@fsugar.be>.
% Permission is granted to copy, distribute and/or modify this document
% under the terms of the GNU Free Documentation License, Version 1.2
% or any later version published by the Free Software Foundation.

\documentclass{beamer}

\usetheme{PaloAlto}

\usepackage[french]{babel}
\usepackage[utf8]{inputenc}

\setbeamercovered{transparent}

\title{Introduction à Ruby}
\author{Rémi "FiFouille" Laurent}
\institute{FSUGAr \&\\
\#ubuntu-fr-classroom}
\date{14 mars 2007}

\begin{document}

\frame{\titlepage}

\part{Vue d'ensemble}
\frame{\partpage}

\section{Historique}
\frame{\tableofcontents[current]}

\frame
{
	\frametitle{Qui, quand, où ?}
	\begin{itemize}
	\item Ruby est l'initiative du japonais Yukihiro "Matz" Matsumoto.

	\item Il a commencé à écrire ce langage en 1993,\\
	la première version publique date de 1995.
	
	\item Actuellement Ruby en est à la version 1.8.\\
	La version de développement 1.9 débouchera sur Ruby 2.0.

	\item Ruby est distribué sous les termes de la \emph{GNU GPLv2}\\
	ainsi que la \emph{Ruby License}.
	\end{itemize}
	
}

\section{Utilisations}
\frame{\tableofcontents[current]}

\frame
{
	\frametitle{Domaines d'utilisation de Ruby}
	Ruby peut avoir de nombreuses applications :
	\begin{itemize}
	\item Script : sysadmin, génération de code/documents
	\item Applications \emph{classiques} se basant sur nombre de bibliothèques disponibles
	\item Web : Ruby on Rails, ERB, ...
	\item Apprentissage, test : irb, simplicité et lisibilité du code
	\end{itemize}
}

\section{Technique}
\frame{\tableofcontents[current]}

\subsection{Informations}

\frame
{
	\frametitle{Informations techniques diverses}
	Quelques caractéristiques techniques :
	\begin{itemize}
		\item langage de script
		\item dynamique
		\item ramasse miette / garbage collector
		\item procédural - orienté objet - fonctionnel
		\item \bf{tout} est objet
	\end{itemize}
}

\subsection{Rapidité}

\frame
{
	\frametitle{Machines virtuelles}
	Actuellement Ruby est relativement plus lent que du Python par exemple\\
	d'où l'idée d'utiliser des VM (Machines Virtuelles)
	\begin{itemize}
	\item Yarv - Yet Another Ruby VM - pour Ruby 2.0 - bientôt
	\item JRuby - utilisation de la JVM (Java) - opérationnel
	\item Rite - première VM prévue pour Ruby 2.0 - projet mort ?
	\item Parrot - la VM prévue pour Perl 6 - ???
	\end{itemize}
}

%-------------------
\part{Un peu de pratique}

\frame{\partpage}
\section{Installation}
\frame{\tableofcontents[current]}
\subsection{Indispensables}

\frame
{
	\frametitle{Paquets utiles}
	Les applications à installer sont :
	\begin{itemize}
	\item Ruby - l'interpréteur
	\item irb - Interactive Ruby - interpréteur interactif
	\end{itemize}
	\pause
	On peut encore installer :
	\begin{itemize}
	\item Ruby Gems - installeur de 'paquets' ruby
	\pause
	\item Rake - Ruby make
	\end{itemize}
}
\subsection{Ubuntu/Debian}
\frame
{
	\frametitle{Les commandes}
	\verb!sudo apt-get install ruby1.8 irb1.8!

	\pause
	\verb!sudo apt-get install rubygems rake!
	\pause

	\vspace{1cm}
	\emph{Astuce :}\\
	\verb!echo "require 'irb/completion'" >> \$HOME/.irbrc!\\
	Vous aurez alors une auto complétion dans \emph{irb}
}

\section{Premiers pas}
\frame{\tableofcontents[current]}

\subsection{Hello World!}

\begin{frame}[fragile]
	\frametitle{Hello World!}
	Dans irb :
	\begin{verbatim}
puts "Hello World!"
	\end{verbatim}

	\pause
	Dans un fichier, hello.rb:
\begin{verbatim}
#!/usr/bin/ruby -w
puts "Hello World!"
\end{verbatim}
	\pause
	\begin{itemize}
	\item -w active les avertissements\\
	\item \verb!ruby -c hello.rb! vérifie la syntaxe
	\item n'oubliez pas de rendre hello.rb exécutable ...
	\end{itemize}
\end{frame}

\subsection{Hello \#\{you\} !}

\begin{frame}[fragile]
	\frametitle{Hello \#\{you\} !}
	\begin{verbatim}
you = gets
puts "Hello " + you + " !"
you = gets.chomp
puts "Hello #{you} !"
	\end{verbatim}
	\pause
	On obtient :
	\begin{verbatim}
fifi <ENTER>
Hello fifi
 !
fifi <ENTER>
Hello fifi !
	\end{verbatim}
\end{frame}

\section{"Types" de base}
\frame{\tableofcontents[current]}
\subsection{Numériques}
\begin{frame}[fragile]
	\frametitle{Numeric, Integer, Fixnum, Bignum, Float}
	Hiérarchie :\\
	\ldots
	\begin{itemize}
	\item Numeric	\begin{itemize}
			\item Integer 	\begin{itemize}
					\item Fixnum
					\item Bignum
					\end{itemize}
			\item Float
	 		\end{itemize}
	\end{itemize}

	\pause
	\begin{verbatim}
puts 5              => 5
puts 5*2            => 10
a = 5**2
puts a              => 25
puts a + 10         => 35
puts "5" * 4        => 5555  ?!&?
	\end{verbatim}
\end{frame}

\subsection{Chaînes de caractères}
\begin{frame}[fragile]
	\frametitle{Chaînes de caractères - String}
	\begin{verbatim}
puts "foobar"              => foobar
str = "foo" + "bar"
puts str + " hello"        => foobar hello
puts str * 2               => foobarfoobar
puts "_#{str}_"            => _foobar_
puts "foobar".upcase       => FOOBAR
	\end{verbatim}
\emph{puts} ajoute le retour à la ligne, alors que \emph{print} non.
\end{frame}

\subsection{Tableaux}
\begin{frame}[fragile]
	\frametitle{Les tableaux - Array}
	\begin{verbatim}
arr1 = [1,2,3]
arr1[0]              => 1
arr1[-1]             => -3
arr1[1..2]           => [2, 3]
arr2 = []
arr2 << 2 << 4 << 3
arr1 + arr2          => [1, 2, 3, 2, 4, 3]
arr1 & arr2          => [2, 3]
arr1 - arr2          => [1]
(arr1+arr2).sort     => [1, 2, 2, 3, 3, 4]
	\end{verbatim}
\end{frame}

\subsection{Tables de hachage}
\begin{frame}
	\frametitle{Définition - Hash}
	Il s'agit d'une table où des \emph{clés} correspondent à des \emph{valeurs}.
	Une fonction de hachage calcule une clé unique pour une clé donnée et lui fait correspondre une valeur.
	\begin{itemize}
		\item clé 'pomme' - valeur 'rouge'
		\item collision : 'pomme' ne peut être 'rouge' et 'verte' à la fois
		\item fonction de hachage : répartition uniforme des index
		\item rapide d'accès par rapport aux tableaux (surtout pour les grandes tailles)
	\end{itemize}
\end{frame}

\subsubsection{Exemples}
\begin{frame}[fragile]
	\frametitle{Exemples - Hash}
	\begin{verbatim}
		h = { 'pomme' => 'rouge' }
		h[42] = "la réponse à ..."
		puts h['pomme'] + h[42]
		puts h.has_key?'pomme'      => true
		puts h.has_key?('poire')    => false
		h = Hash.new(5)
		puts h[123]                 => 5
		h[123] += 2
		puts h[123]                 => 7

		h = { 'pomme' => [ 'rouge', 'verte']\
		   'banane' => 'jaune' }
	\end{verbatim}
\end{frame}

\subsubsection{Application}
\begin{frame}[fragile]
	\frametitle{Application pratique}
	Nous allons compter le nombre de mots dans une phrase :
	\begin{verbatim}
str = "Les pommes sont rouges ou vertes,\
  les bananes jaunes et\
  les poires sont vertes ou jaunes"
h = Hash.new(0)
str.split(/ /).each { |mot| h[mot] += 1 }
puts "jaunes : #{h['jaunes']}"  => 2
puts "rouges : #{h['rouges']}"  => 1
puts "orange : #{h['orange']}"  => 0
	\end{verbatim}
\pause
PS : si vous n'avez pas tout compris, ça va venir ;)
\end{frame}

\subsection{Conversion}
\begin{frame}[fragile]
	\frametitle{Conversions entre types (classes)}
	Les conversions sont possibles : 
	\begin{itemize}
		\item entier $\rightarrow$ chaîne de caractère --- \verb!5.to_s!
		\item entier $\rightarrow$ réel --- \verb!6.to_f!
		\item chaîne $\rightarrow$ réel --- \verb!"3.14".to_f!
		\item tableau $\rightarrow$ chaîne de caractère --- \verb![2,3].to_s!
		\item range $\rightarrow$ tableau --- \verb!(1..5).to_a!
		\item \ldots
	\end{itemize}
	Attention aux arrondis, mise à plat, \ldots 
\end{frame}

\part{Commençons à programmer}
\frame{\partpage}

\section{Opérateurs}
\frame{\tableofcontents[current]}
\subsection{Arithmétique}
\begin{frame}[fragile]
	\frametitle{Opérateurs arithmétiques de base}
	\begin{verbatim}
puts "hello" * 2              => "hellohello"
[1,2,3,4] - [2,3]             => [1,4]
str = "hello"
str << " world!"
puts str + "%0.2f" % 4.425    => hello world!4.42
[1,2,3] * 2                   => [1,2,3,1,2,3]
puts 5 % 3                    => 2
	\end{verbatim}
\end{frame}

\subsection{Comparaison}
\begin{frame}[fragile]
	\frametitle{Opérateurs de comparaison}
	\begin{description}
		\item [==, !=] (in)égalité au sens strict\\
		\verb/5 == 5 , "hello" != "Hello"/
		\item [\verb!<=>!] comparaison, renvoie -1, 0 ou +1 selon la comparaison, utilisé pour spécifier un ordre de tri (Array\#sort par exemple)
		\item [===] comparaison utilisée dans le cadre de\\
		\emph{case ... when}\\
			\begin{verbatim}
(5..10)    ===  6    => true
('a'..'z') === 'b'   => true
('a'..'z') === 'Z'   => false
			\end{verbatim}
		\item [\verb!<,>,<=,>=!] classiques dirons-nous
	\end{description}
\end{frame}

\subsection{Logique}
\begin{frame}[fragile]
	\frametitle{Opérateurs logiques}
	Opérateurs logiques classiques qui ont, entre autres, des propriétés intéressantes sur les tableaux :
	\begin{verbatim}
[1,2,3] & [1,2]        => [1, 2]
[1,2,3] | [1,2,4]      => [1, 2, 3, 4]
7 ^ 2  (111^010=110)   => 5
6 & 2  (110&010=010)   => 2
	\end{verbatim}
\end{frame}

\section{Blocs conditionnels}
\frame{\tableofcontents[current]}

\subsection{if elsif else end}
\begin{frame}[fragile]
	\frametitle{if \emph{expr} then ... elsif \emph{expr} ... else ... end}
	\begin{verbatim}
val = gets
if ( val == 6 )
   puts "c'est 6"
elsif (1..5) === val
   puts "entre 1 et 5 compris"
else
   puts "autre chose"
end

puts "c'est 6" if val == 6
puts "c'est pas 6" unless val == 6
	\end{verbatim}
\end{frame}

\subsection{for x in y}
\begin{frame}[fragile]
	\frametitle{for x in y ... f(x) end}
	\begin{verbatim}
for i in [1,3,2,4].sort.reverse
   puts "valeur = #{i}"
end

for i in (2..10)
   puts "2 exposant #{i} = #{2**i}"
end
	\end{verbatim}
\end{frame}

\subsection{while do ...}
\begin{frame}[fragile]
	\frametitle{while \emph{expr} do ... end}
	\begin{verbatim}
i = 2
while i <= 256 do
   puts i
   i = i*i
end
# avec une expression rationnelle
#  pour nos plus fidèles auditeurs
while s = gets
   next if ~ /^#/
   break if ~ /^quitter$/
   puts s
end
	\end{verbatim}
\end{frame}

\subsection{case where else}
\begin{frame}[fragile]
	\frametitle{case \emph{expr} when \emph{expr} then ... else ... end}
	\begin{verbatim}
var = gets
case var
   when /quitter/
      puts "quitter"
      exit
   when /heure/
      puts Time.now
   else
      puts "non reconnu"
end
	\end{verbatim}
\end{frame}

\section{I/O}
\frame{\tableofcontents[current]}

\subsection{Lecture}
\begin{frame}[fragile]
	\frametitle{Lecture dans un fichier}
	\begin{verbatim}
fd = open("monfichier", "r")
fd.each do |ligne|
   puts ligne
end
fd.close
	\end{verbatim}
On ouvre donc le fichier, en lecture \emph{"r"} et ensuite\\
on utilise un itérateur sur le 'descripteur' de fichier obtenu.
\begin{verbatim}
fd.each do |ligne|
\end{verbatim}
projette ligne par ligne dans la variable \emph{ligne}, variable \emph{ligne} qu'on affiche avec \emph{puts}.
\end{frame}

\subsection{Écriture}
\begin{frame}[fragile]
	L'opération d'écriture n'est pas fort différente :
	\begin{verbatim}
fd = open("monfichier", "w+")

10.times { |i| fd.puts "#{i} : #{i*i}" }

fd.close
	\end{verbatim}
Il s'agit du même principe que pour la lecture, sauf que nous avons spécifié le \emph{bloc} entre \emph{parenthèses} et pas entre \emph{do ... end}. Voyons maintenant ce qu'est un itérateur et un bloc.

\pause
PS : les modes sont les mêmes qu'en C avec \emph{fopen(3)} : \emph{man fopen}
	\frametitle{Écriture dans un fichier}
\end{frame}

\part{Principes avancés}
\frame{\partpage}

\section{Itérateurs}
\frame{\scriptsize{\tableofcontents[current]}}
\subsection{Définition}
\begin{frame}[fragile]
	\frametitle{Itérateurs - Définition}
	Un itérateur permet de parcourir une collection de données, et ce, d'une manière unifiée, quelle que soit la représentation interne de cette collection de donnée.
	\newline
	\pause

	Dès lors il permet, à l'aide de mécanismes sensiblement ressemblants, de parcourir : un tableau, une liste, un arbre, une table de hachage, une base de donnée, un fichier, ...
\end{frame}

\subsection{Exemples}
\begin{frame}[fragile]
	\frametitle{Itérateurs - Exemples}
	\begin{verbatim}
	[1,2,3].each { |i| puts i }

	h = { 'banane' => 'jaune', 'poire' => 'verte',\
	   'pomme' => 'rouge' }
	h.each { |k,v| puts "#{k} est #{v}" }

	#exemple en Ruby on Rails
	list = Clients.find(:all,\
	    :conditions => [ 'nom ilike ?', 'jacque' ])
	list.each { |c| c.email = 'foo@bar.com'; c.save }
\end{verbatim}

\end{frame}

\section{Blocs}
\frame{\scriptsize{\tableofcontents[current]}}
\subsection{Définition}
\begin{frame}[fragile]
	\frametitle{Blocs \& Procs - Définition}
	Un peu comme les pointeurs de fonction en C, Ruby permet d'associer une fonction à une variable.

	Cependant Ruby va plus loin, non seulement avec les \emph{closures} qui permettent d'accéder à une partie de l'environnement manipulé, mais encore en permettant la création de bloc/proc dynamiques.

	Un bloc ou proc peut être vu comme un bout de code associé à un symbole et réutilisable facilement dans différents contextes.
\end{frame}

\subsection{Exemples 1}
\begin{frame}[fragile]
	\frametitle{Blocs \& Procs - Exemples 1}
	\begin{verbatim}
	heure = lambda { Time.now.to_s }
	def do_n_times(n, &block)
	  lambda { n.times { puts yield } }
	end

	proc1 = do_n_times(3) { "il est " + heure.call }
	proc2 = do_n_times(3) { sleep 1;\
	   "il est " + heure.call }

	proc1.call
	2.times { proc2.call }
	\end{verbatim}
\end{frame}

\subsection{Exemples 2}
\begin{frame}[fragile]
	\frametitle{Blocs \& Procs - Exemples 2}
	\begin{verbatim}
	arr = ['11','2','33','4','55']
	arr.sort { rand }
	arr.sort { |x,y| x.length <=> y.length }

	class Hash
	  def each_times(&block)
	    each { |k,v| k.times { yield v }  }
	  end
	end
	h = { 2 => "hello", 1 => "coin", 4 => "pouet" }

	h.each_times { |s| puts "valeur : " + s }
	\end{verbatim}
\end{frame}

\section{Regex}
\frame{\scriptsize{\tableofcontents[current]}}
\subsection{Définition}
\begin{frame}[fragile]
	\frametitle{Expressions rationnelles - Définition}
	Une expression rationnelle c'est :\\
	une notation permettant de décrire des chaînes de caractères, en gros :
	\begin{itemize}
		\item de repérer des schémas donnés de chaîne de caractères
		\item de les manipuler
		\item (d'impressionner|de traumatiser) (sa copine|ses copains|son patron)
	\end{itemize}
	Pour plus d'informations, je vous renvoie à une autre présentation ;)
\end{frame}

\subsection{Exemples}
\begin{frame}[fragile]
	\frametitle{Expressions rationnelles - Exemples}
	\begin{verbatim}
	#bon courage ;)
	str = "bonjour, comment va ?"
	str.match(/^bon(.*),.+(m{2,}).+(..\?)$/)
	foo, bar, baz = $1, $2, $3.gsub(/ /, 'h')

	puts "#{bar}h, quelle #{foo}née ! #{baz}"
	
	puts "bonjour" if str =~ /^bonjour/
	puts str
	puts "bien" if str =~ /va\s*\?$/
	\end{verbatim}
\end{frame}

\section{Exceptions}
\frame{\scriptsize{\tableofcontents[current]}}
\subsection{Définition}
\begin{frame}[fragile]
	\frametitle{Exceptions - Définition}
	Avec de simples codes de retour il est parfois difficile de remonter une erreur et de la définir précisément, il est parfois encore plus difficile de se remettre proprement d'une erreur rencontrée.
	\newline

	Les exceptions sont là pour palier à ce problème, en définissant précisément une erreur, et en permettant de terminer proprement chaque partie ou étape du programme.
	\newline

	Les cas les plus classiques sont la fermeture de fichiers ou de connexions réseaux, mais d'autres sont envisageables bien entendu.
\end{frame}

\subsection{Exemples}
\begin{frame}[fragile]
	\frametitle{Exceptions - Exemples}
	\begin{verbatim}
	filename = "fichier.txt"
	tmpfilename = "/tmp/" + filename
	begin
	  fd = open(filename, 'w+')
	  fd.puts Time.now.to_s
	rescue
	  raise "erreur" if filename == tmpfilename
	  $stderr.puts "essai avec un fichier temporaire"
	  filename = tmpfilename
	  retry
	ensure
	  fd.close if fd
	end
	\end{verbatim}
\end{frame}

\section{Orienté Objet}
\frame{\scriptsize{\tableofcontents[current]}}
\subsection{Parlons-en}
\begin{frame}[fragile]
	\frametitle{Orienté Objet}
	Vous voulez qu'on en parle ?
	\newline
	\pause

	Parce qu'il paraît que ça ferait de trop pour une seule fois ;)
\end{frame}

\part{Conclusion}
\frame{\partpage}

\section{Conclusion}
\frame{\tableofcontents[current]}
\begin{frame}
	\frametitle{Conclusion}
	Ruby semble être un langage fort agréable,\\
	facile à apprendre et utiliser,\\
	qui dispose de nombre de bibliothèques intéressantes,\\
	qui propose des extensions simples à mettre en oeuvre,\\
	une approche orientée objet omniprésente,\\
	et de nombreux domaines d'application.

	\vspace{1cm}
	\pause
	Pour ceux qui ne l'auraient pas compris, l'auteur de ces slides \emph{apprécie} Ruby
\end{frame}

\section{Documentation}
\begin{frame}
	\frametitle{Documentation disponible}
	Il existe beaucoup de documentation accessible gratuitement, la plupart du temps :
	\begin{itemize}
		\item \url{http://www.rubycentral.com/book/} - EN
		\item \url{http://pine.fm/LearnToProgram/} - EN/FR
		\item \url{http://www.ruby-lang.org/en/documentation/} - EN
		\item The Pragmatic Programmer Guide - 2nd Edition par Dave Thomas
		\item \$ gem\_server et puis http://localhost:8808\\
			si vous avez installé des modules avec \emph{rubygems}
		\item Agile Web Development with Rails\\
			pour ceux qui voudraient essayer Ruby On Rails
	\end{itemize}
\end{frame}

\end{document}
