Proc Placeholder

Краен срок
05.12.2014 12:00

Срокът за предаване на решения е отминал

Proc Placeholder

Много обичаме съкратения вариант за извикване на блок през символ.

["all", "fancy", "words"].map(&:length)    # [3, 5, 5]

Толкова много, че започваме да страдаме поради факта, че няма как да подаваме аргументи на блок-а по също толкова елегантен начин, а се налага да разписваме целия proc.

(1..5).map { |n| n ** 2 }    # [1, 4, 9, 16, 25]

Понеже знаем, че Ruby е красив, елегантен и в същото време мощен, ще се опитаме да запълним тази "липса".

Целта на това предизвикателство е да дефинирате въображаемия обект P. Този обект ще играе ролята на placeholder, върху който можем да извикваме методи, подавайки им аргументи. Тези методи ще бъдат извиквани върху всеки един елемент от колекцията, подобно на стандартен блок. Например:

(1..5).map(&P ** 2)    # [1, 4, 9, 16, 25]

Тук виждаме как методът ** се извиква върху фиктивния обект P с аргумент 2, което кара map да приложи тази операция върху всеки обект от колекцията. Или пък:

[[1, 2, 3, 8], [4, 5], [6]].map(&P.select(&:even?))    # [[2, 8], [4], [6]]

Ако не извикаме метод на обекта P, очакваме той да работи като идентитет:

(1..5).map(&P)    # [1, 2, 3, 4, 5]

One more thing..

Въображаемият обект P трябва да е способен да прехвърли всяко съобщение на правилния получател, дори неща от рода на instance_eval и __id__. Подсказка: прокси.

Решения

Екатерина Горанова
  • Коректно
  • 5 успешни тест(а)
  • 0 неуспешни тест(а)
Екатерина Горанова
class Proxy
instance_methods.each { |m| undef_method m unless m =~ /(^__send__$|^object_id$)/ }
def method_missing(name, *args, &block)
Proc.new { |object| object.send(name, *args, &block) }
end
def to_proc
Proc.new { |object| object }
end
end
P = Proxy.new
.....

Finished in 0.00285 seconds
5 examples, 0 failures
Константин Тодоров
  • Некоректно
  • 4 успешни тест(а)
  • 1 неуспешни тест(а)
Константин Тодоров
class Proxy < Object
def to_proc
Proc.new { |n| n }
end
private
def method_missing(name, *args, &block)
return Proc.new { |n| n.send(name, &block) } if block_given?
Proc.new { |n| n.send(name, *args) }
end
end
class Object
P = Proxy.new
end
...F.

Failures:

  1) P could be used with methods from BasicObject
     Failure/Error: expect((1..5).select(&P == 2)).to eq [2]
     TypeError:
       wrong argument type FalseClass (expected Proc)
     # /tmp/d20150828-1247-1l6k9iq/spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.0029 seconds
5 examples, 1 failure

Failed examples:

rspec /tmp/d20150828-1247-1l6k9iq/spec.rb:14 # P could be used with methods from BasicObject
Николина Гюрова
  • Некоректно
  • 4 успешни тест(а)
  • 1 неуспешни тест(а)
Николина Гюрова
class Proxy
attr_reader :to_proc
def initialize(&block)
@to_proc = block || Proc.new{|x| x}
end
def method_missing(name, *args, &block)
Proxy.new { |x| @to_proc.call(x).__send__(name, *args, &block) }
end
end
P = Proxy.new
...F.

Failures:

  1) P could be used with methods from BasicObject
     Failure/Error: expect((1..5).select(&P == 2)).to eq [2]
     TypeError:
       wrong argument type FalseClass (expected Proc)
     # /tmp/d20150828-1247-1gw3n1y/spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.00288 seconds
5 examples, 1 failure

Failed examples:

rspec /tmp/d20150828-1247-1gw3n1y/spec.rb:14 # P could be used with methods from BasicObject
Ясен Трифонов
  • Некоректно
  • 0 успешни тест(а)
  • 5 неуспешни тест(а)
Ясен Трифонов
class P < BasicObject
def self.method_missing(m, *args, &block)
Proc.new do |obj|
obj.send m, *args
end
end
end
FFFFF

Failures:

  1) P could be used with one argument
     Failure/Error: expect((1..5).map(&P ** 2)).to eq [1, 4, 9, 16, 25]
     NameError:
       uninitialized constant P::Proc
     # /tmp/d20150828-1247-gcgfiw/solution.rb:3:in `method_missing'
     # /tmp/d20150828-1247-gcgfiw/spec.rb:3:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) P could be used with blocks
     Failure/Error: expect([["some", "lists"], ["of", "words"]].map(&P.map(&:length))).to eq [[4, 5], [2, 5]]
     NameError:
       uninitialized constant P::Proc
     # /tmp/d20150828-1247-gcgfiw/solution.rb:3:in `method_missing'
     # /tmp/d20150828-1247-gcgfiw/spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) P could be used without method calls
     Failure/Error: expect(["this", "should", "remain", "the", "same"].map(&P)).to eq ["this", "should", "remain", "the", "same"]
     NameError:
       uninitialized constant P::Proc
     # /tmp/d20150828-1247-gcgfiw/solution.rb:3:in `method_missing'
     # /tmp/d20150828-1247-gcgfiw/spec.rb:11:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) P could be used with methods from BasicObject
     Failure/Error: expect((1..5).select(&P == 2)).to eq [2]
     TypeError:
       wrong argument type FalseClass (expected Proc)
     # /tmp/d20150828-1247-gcgfiw/spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) P could be really, really ugly but still works
     Failure/Error: expect(["some", "scary", "meta", "stuff"].map(&P.__send__(:length))).to eq [4, 5, 4, 5]
     NameError:
       uninitialized constant P::Proc
     # /tmp/d20150828-1247-gcgfiw/solution.rb:3:in `method_missing'
     # /tmp/d20150828-1247-gcgfiw/spec.rb:19:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.00223 seconds
5 examples, 5 failures

Failed examples:

rspec /tmp/d20150828-1247-gcgfiw/spec.rb:2 # P could be used with one argument
rspec /tmp/d20150828-1247-gcgfiw/spec.rb:6 # P could be used with blocks
rspec /tmp/d20150828-1247-gcgfiw/spec.rb:10 # P could be used without method calls
rspec /tmp/d20150828-1247-gcgfiw/spec.rb:14 # P could be used with methods from BasicObject
rspec /tmp/d20150828-1247-gcgfiw/spec.rb:18 # P could be really, really ugly but still works
Кристиан Цветков
  • Некоректно
  • 4 успешни тест(а)
  • 1 неуспешни тест(а)
Кристиан Цветков
class P < BasicObject
def self.method_missing(name, *args, &block)
if name.to_s == 'to_proc'
::Object::Proc.new { |arg| arg }
else
::Object::Proc.new { |arg| arg.send(name, *args, &block) }
end
end
end
...F.

Failures:

  1) P could be used with methods from BasicObject
     Failure/Error: expect((1..5).select(&P == 2)).to eq [2]
     TypeError:
       wrong argument type FalseClass (expected Proc)
     # /tmp/d20150828-1247-s9vw23/spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.00288 seconds
5 examples, 1 failure

Failed examples:

rspec /tmp/d20150828-1247-s9vw23/spec.rb:14 # P could be used with methods from BasicObject
Герасим Станчев
  • Некоректно
  • 4 успешни тест(а)
  • 1 неуспешни тест(а)
Герасим Станчев
class Proxy
def method_missing(method, *args, &block)
proc { |arg| arg.send method, *args, &block }
end
def to_proc
proc { |arg| arg }
end
end
P = Proxy.new
...F.

Failures:

  1) P could be used with methods from BasicObject
     Failure/Error: expect((1..5).select(&P == 2)).to eq [2]
     TypeError:
       wrong argument type FalseClass (expected Proc)
     # /tmp/d20150828-1247-1ovpwnx/spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.00292 seconds
5 examples, 1 failure

Failed examples:

rspec /tmp/d20150828-1247-1ovpwnx/spec.rb:14 # P could be used with methods from BasicObject
Димитър Димитров
  • Некоректно
  • 0 успешни тест(а)
  • 5 неуспешни тест(а)
Димитър Димитров
# foo
FFFFF

Failures:

  1) P could be used with one argument
     Failure/Error: expect((1..5).map(&P ** 2)).to eq [1, 4, 9, 16, 25]
     NameError:
       uninitialized constant P
     # /tmp/d20150828-1247-ojphhg/spec.rb:3:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) P could be used with blocks
     Failure/Error: expect([["some", "lists"], ["of", "words"]].map(&P.map(&:length))).to eq [[4, 5], [2, 5]]
     NameError:
       uninitialized constant P
     # /tmp/d20150828-1247-ojphhg/spec.rb:7:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) P could be used without method calls
     Failure/Error: expect(["this", "should", "remain", "the", "same"].map(&P)).to eq ["this", "should", "remain", "the", "same"]
     NameError:
       uninitialized constant P
     # /tmp/d20150828-1247-ojphhg/spec.rb:11:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) P could be used with methods from BasicObject
     Failure/Error: expect((1..5).select(&P == 2)).to eq [2]
     NameError:
       uninitialized constant P
     # /tmp/d20150828-1247-ojphhg/spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) P could be really, really ugly but still works
     Failure/Error: expect(["some", "scary", "meta", "stuff"].map(&P.__send__(:length))).to eq [4, 5, 4, 5]
     NameError:
       uninitialized constant P
     # /tmp/d20150828-1247-ojphhg/spec.rb:19:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.00685 seconds
5 examples, 5 failures

Failed examples:

rspec /tmp/d20150828-1247-ojphhg/spec.rb:2 # P could be used with one argument
rspec /tmp/d20150828-1247-ojphhg/spec.rb:6 # P could be used with blocks
rspec /tmp/d20150828-1247-ojphhg/spec.rb:10 # P could be used without method calls
rspec /tmp/d20150828-1247-ojphhg/spec.rb:14 # P could be used with methods from BasicObject
rspec /tmp/d20150828-1247-ojphhg/spec.rb:18 # P could be really, really ugly but still works