Repaso

  1. ¿Cuanto vale self en las líneas 5-8 cuando my_attr_reader es llamado desde la línea 14?
    MacBookdeCasiano:chapter8ReflectionandMetaprogramming casiano$ cat -n myAccessors.rb 
         1  class Module
         2    def my_attr_reader(*syms)
         3      syms.each { |s|
         4        class_eval %{
         5                      def #{s} 
         6                        @#{s} 
         7                      end
         8                    }
         9      }
        10    end
        11  end
        12  
        13  class Chuchu
        14    my_attr_reader :a, :b
        15  
        16    def initialize(a,b)
        17      @a, @b = a, b
        18    end
        19  end
    
  2. Rellene las partes que faltan en el código de la clase Quiz que implementa un DSL para la escritura de cuestionarios. Comente el código.
    class Quiz
      RIGHT = :right
      WRONG = :wrong
    
      attr_accessor :name, :_________ 
    
      def initialize(name, &block)
        self.name = name
        self.questions = __
    
        @counter = 0
        _____________ &block
      end
    
      def question(text, answers)
        q = Question.new(text, answers)
        questions << q 
        @_______ = _
      end
    
    
      def to_s
        out = <<"EOQUIZ"
    #{self.name}
    
    #{self.questions.____("\n")}
    EOQUIZ
      end
    
      def wrong
        @counter += 1
        [_______________]
      end
    
      def right
        @counter+= 1
        [_______________]
      end
    
      def run
        counter=0
        puts self.name+"\n\n"
        self.questions.each { |q| counter += 1 if q.ask }
        puts "#{counter} respuestas correctas de un total de #{@_________.size}."
      end
    end
    
  3. Rellene las partes que faltan en el código de la clase Question que implementa los objetos question para el DSL visto en clase para la escritura de cuestionarios. Comente el código.
    class Question
      ORDER = 0
      KIND = 1
      attr_accessor :text, :answers
    
      def initialize(text, answers)
        @text = text
        @answers = answers.map { |k, v| _________________________________ }.sort
      end
    
      def to_s
        output = <<"EORECIPE"
    #{_____}
    
    #{
        out = ""
        @answers.each do |answer|
          out << "  #{answer}\n"
        end
        ___
    }
    EORECIPE
      end
    
      def ask
        begin
          puts self
          print "Su respuesta: " 
          answerno = gets.to_i - 1
        end while (answerno < 0 or answerno >= @_______.______)
        @answers[________].is_right? 
      end
    
    end
    
  4. Rellene las partes que faltan en el código de la clase Answer que implementa las respuestas en el DSL para la escritura de cuestionarios. Comente el código.
    class Answer
      attr_accessor :____, :_____, :______
    
      def initialize(order, kind, answer)
        @kind, @order, @answer = kind, order, answer
      end
    
      def to_s
        "#{@order} -  #{answer}"
      end
    
      def is_right?
        ____________________
      end
    
      def ___(other)
        __________________________
      end
    
    end
    
  5. Complete las partes que faltan en el siguiente código que implementa el método prun de la práctica Procesos Concurrentes. Comente el programa.
    #!/usr/___/env ____ -w
    
    def deb(m) 
      puts "#{$$}: #{m}" if $DEBUG
    end
    
    
    def getResult(chan)
      Marshal.____(chan.____)
    end
      
    def prun(p)
      pid, name, read = {}, {}, {}
      p.each { |n, code|
        read[n], write = IO.____
    
        pid[n] = fork do
          read[n]._____
    
          res = _________(n)
    
          write.syswrite ____________(res)
    
        end # fork
    
        write._____
      }
    
      name = pid.invert
      
      result = {}
      p.length.times { 
        i, s = Process._____ 
        n = _______
    
        result[n] = getResult(read[n])
        deb "Finished process '____' pid=____ with status #{s} result = ____________"
      }
      ______
    end
    
    res = prun(
         :one     => lambda { |n| "#{n} is 1" },
         :three   => lambda { |n| "#{n} is 3" },
         'two'    => lambda { |n| n*4 }
    )
    
  6. Complete las partes que faltan en el siguiente código de la práctica Ordenar por Calificaciones que implementa la ordenación de un ficheros de notas con el formato:
    Ferrer Pérez, Eduardo & 9'6\\
    
    Se ordenan en orden decreciente de calificaciones. Comente el programa.
    ~/rubytesting$ cat -n calif.rb 
         1  f = File.open('notas')
         2  x = f._________
         3  
         4  y = x.map { |alu| alu =~ /_____________________/;  ________ }
         5  h =  ____[__________]
         6  h.keys.each { |alu| h[alu].gsub!(/__________)/, '_____'); h[alu] = h[alu].____ }
         7  
         8  s = h.sort { |a,b| ____ <=> ____ }
         9  s.each { |x| puts "_________________________" }
    

  7. Complete las partes que faltan en el siguiente código de la práctica La Calculadora que implementa una calculadora extensible de expresiones en postfijo que admiten variables y asignación. Comente el programa.
     1  class PostfixCalc
     2  
     3    attr_reader :stack
     4    attr_accessor :st
     5  
     6    def initialize(f) 
     7      @f = {
     8        '+' => lambda { |a,b| a+b },
     9        '*' => lambda { |a,b| a*b },
    10        '-' => lambda { |a,b| a-b },
    11        '/' => lambda { |a,b| a/b },
    12        'p' => lambda { _____________ },
    13        '!' => lambda { __________ },
    14        '=' => lambda { _____________________ },
    15      }
    16      @f._____!(f)
    17      @st = ________
    18      @stack = __
    19    end
    20  
    21   def eval(expr)
    22      expr.gsub!(/____________________/, '\1 \2') # Se admite a= y b!
    23      expr.split(/___/).each do |x|
    24        case x
    25          when *@f.keys
    26            f = _____
    27            ops = @stack.pop _______
    28            b = f.call(_____)
    29            @stack.push __ if __
    30          when /^-?\d+(\.\d+)?$/
    31            @stack.push ______
    32          when /^[a-zA-Z_]\w*$/
    33            _____________
    34          else
    35            ___________________________________________________________________       
    36        end
    37      end # each
    38    end
    39  end
    ..  ...
    

  8. Complete las partes que faltan en el siguiente fragmento de código que implementa la práctica Conjuntos usando arrays. Comente el programa.
     1  class Set2 
     2  
     3    attr_accessor :sep
     4    attr_reader :a
     5    protected :a
     6  
     7    def initialize(a)
     8      @sep = ', '
     9      @a = a.uniq.____
    10    end
    11  
    12    def to_s
    13      _______(@sep)
    14    end
    15  
    16    def length 
    17      _________
    18    end
    19  
    20    alias cardinal ______
    21  
    22    def +(o)
    23      Set2.new(________)
    24    end
    25  
    26    def ^(o) # interseccion
    27      Set2.new(________)
    28    end
    29  
    30    def -(o)
    31      Set2.new(________)
    32    end
    33  
    34    def include?(x)
    35      _____________
    36    end
    37  
    38    def <(s)
    39      if @a.length < s.a.length 
    40        return true if @a.all? { |m| ______________ }
    42      end
    43      return false
    44    end
    45  
    54    def ==(s)
    55      _________
    56    end
    57  
    58    def <=(s)
    59      _________________________
    60    end
    
  9. ¿Cual es la diferencia entre dup y clone?
  10. ¿Cómo se llama el método que nos permite declarar un método de clase como privado?
  11. ¿Que hace El método const_set de la clase Module?
  12. ¿Que retorna el método fork? ¿Que argumentos lleva?
  13. ¿Que retorna el método pipe? ¿En que clase está?
  14. ¿Que hace el método wait2?
  15. ¿Que hace el método exit!?
  16. ¿Que es un proceso zombi?
  17. ¿Que diferencias hay entre syswrite y puts?
  18. ¿Cómo funciona el método popen? (véase por ejemplo [*])
      popen(cmd_string, mode="r" ) {|io| block } => obj
    
  19. ¿Que es YAML? ¿Para que sirve? (véase por ejemplo [*])
  20. ¿Cual es el resultado?
    >> ww ||= 8
    => 
    >> ww ||= 9
    =>
    
  21. Complete el código que falta. La clase SerializableProc implementa bloques de código serializables (véase [*]):
    class SerializableProc
    
       def initialize( block )
         @block = block
         @block.sub!(/^/,'lambda ') unless @block =~/^\s*(?:lambda|proc)/
         @func = eval "#{@block}"
       end
    
    
       def call(* args)
         __________(* args)
       end
    
       def arity
         @func.arity
       end
    
       def _____(limit)
         ______
       end
    
       def ____._____(s)
         ________(s)
       end
    end
    
  22. ¿Cuales son las salidas?
    >> def tutu(n,m, &b) b.call() end
    => nil
    >> tutu 2, {:a =>1, :b =>2} { puts "hello" }
    
    
    >> tutu(2,{:a =>1, :b =>2}) { puts "hello" }
    
  23. ¿Que hace el método extend cuando es llamado en un objeto? ¿Que argumentos recibe? ¿Cual es la salida de estas sentencias? (véase [*])
    >> module Chuchu
    >> def hello; "hello" end
    >> end
    => nil
    >> s = {}
    => {}
    >> s.extend Chuchu
    => {}
    >> s.hello
    =>
    
  24. ¿Cual es el peligro de usar eval en un entorno distribuído?
  25. Comente el siguiente programa y explica su comportamiento:
        def multiplier(n)
          lambda do |*arr| 
                    arr.collect { |i| i*n } 
                 end
        end
        
        doubler = multiplier(2)
        puts doubler[1, 2, 3]
        
        eval("n = 3", doubler.binding)
        puts doubler.call(1, 2, 3)
        
        eval("n = 5", doubler)
        puts doubler.call(1, 2, 3)
    
  26. ¿Que diferencias hay entre instance_eval, class_eval y eval?
  27. ¿Que es un DSL? ¿Que es un DSL interno o empotrado?

Repase los ejercicios 10.9, 10.8.9, 10.10, y 13.11.

Casiano Rodriguez León 2015-01-07