Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Programação Funcional em Ruby

Programação Funcional em Ruby

The Developers Conference, Porto Alegre, 2015

Juan Ibiapina

September 25, 2015
Tweet

Other Decks in Programming

Transcript

  1. Sumário • Contexto • Paradigmas de Programação • Linguagem Funcional

    • Programação Funcional • Aplicações em Ruby • Resultado • Outros Trabalhos
  2. Arquitetura MVC • Controller: Lida com requests • View: HTML,

    CSS e Javascript • Model: Armazenamento e Lógica de Negócio
  3. Arquitetura MVC • Controller: Lida com requests • View: HTML,

    CSS e Javascript • Model: Armazenamento e Lógica de Negócio
  4. E os outros? Orientação a Objeto Literate Concorrent Genérico Meta

    Reativo Protótipo Processos Aspectos Eventos Data Concept
  5. "The parts constructed at each level of a program are

    used as primitives at the next level."
  6. Conceitos e Práticas • Funções de alta ordem • Imutabilidade

    • Pureza (Ausência de Efeitos Colaterais) • Tipos Algébricos • Pattern Matching
  7. Imutabilidade fn main() { let x = 1; x =

    2; } error: re-assignment of immutable variable `x` [E0384]
  8. Pureza main :: IO () main = do user <-

    createUser process user display user main process :: User -> IO () process user = do -- mutate user
  9. Tipos Algébricos type expr = | Plus of expr *

    expr | Minus of expr * expr | Times of expr * expr | Value of int;;
  10. Pattern Matching let rec eval e = match e with

    | Plus (l, r) -> eval(l) + eval(r) | Minus (l, r) -> eval(l) - eval(r) | Times (l, r) -> eval(l) * eval(r) | Value v -> v;;
  11. def process_name(user) user.name.downcase! user.save! end def process_age(user) user.age %= 100

    end def process user = User.find(params[:id]) process_name(user) process_age(user) user.save! end
  12. def enqueue_next_jobs(job_id) return if deleted? finished_jobs_ids = Media.where(_id: self._id).find_and_modify( {

    "$push" => { "finished_jobs_ids" => job_id }}, { new: true } ).finished_jobs_ids if jobs.where(:job_id.nin => finished_jobs_ids).empty? finish_job_processing else jobs_dependent_of = jobs.dependent_of(job_id) jobs_dependent_of.each do |job| waiting_dependencies = (job.dependencies - finished_jobs_ids) if waiting_dependencies.empty? job.enqueue end end end end
  13. class Video::Download < Operation def validate requires :remote_path end def

    perform remote_path = params[:remote_path] ext = File.extname(remote_path) local_path = LocalStorage.make_tmp_filename(ext) RemoteStorage::Service.new(provider).with_session do |session| session.fetch(remote_path, local_path) end local_path end end
  14. class Fingerprint::Job < Operation def validate requires :fingerprint end def

    perform fingerprint = params[:fingerprint] video = run(Video::Download, remote_path: fingerprint.path) run Fingerprint::Netresult, fingerprint: fingerprint, video: video run Fingerprint::Youtube, fingerprint: fingerprint, video: video end end
  15. class Fingerprint include Mongoid::Document include Mongoid::Uuid field :video_id, type: String

    field :title, type: String field :description, type: String field :exhibition_date, type: DateTime field :path, type: String embeds_one :program embeds_one :channel end
  16. operations ├── fingerprint │ ├── netresult.rb │ ├── youtube.rb │

    ├── create.rb │ └── find.rb └── video └── download.rb