櫓日誌

<< Rubyで内包表現 | main | Binding.of_caller >>
スポンサーサイト

一定期間更新がないため広告を表示しています

| スポンサードリンク | - | | - | - |
続:Rubyで内包表現

配列リテラル([1,2,3]のような配列のことをこう呼ぶらしい)のinitialize上書きは無理っぽいので諦めて、コードを整理してみました(ついでにバグ取りも)。 用語はこちらを参考にさせて頂きました。

書式:
I['value_expression' | 'var <- source',  'predicate_1', 'predicate_2', ・・・, 'predicate_n']

この式は以下のような式に展開されます。

source.select do |var|
  predicate_1(var) &&  predicate_2(var) && ・・・ && predicate_n(var)
end.map do |var|
  value_expression(var)
end
例1:
xs = [10,30,3,-5,1,10,100,-60]
p I['(x*2).abs' | 'x<-xs', 'x < 50']
=> [20, 60, 6, 10, 2, 20, 120]
例2:
def quicksort(x = nil, *xs)
  return []  if x == nil
  quicksort(*I['y' | 'y <- xs', 'y < x']) + [x] + quicksort(*I['y' | 'y <- xs', 'y >= x'])
end
p quicksort(*xs)
=> [-60, -5, 1, 3, 10, 10, 30, 100]
コードはこちら:
require 'active_support/binding_of_caller'

class Intention
  def initialize(value_expression, var, source)
    @value_expression = value_expression
    @var = var
    @source = source
  end
  
  def to_a(predicates, binding)
    predicates << 'true'  if predicates == []
    eval(<<-EOF, binding)
      #@source.select {|#@var|  #{predicates.join('&&')} }.map do |#@var|
        #@value_expression
      end
    EOF
  end
end

class String
  def |(other)
    raise  unless other =~ /^(.+)<-(.+)$/
    Intention.new(self, $1, $2)
  end
end

class I
  def self.[](intention, *predicates)
    raise  unless  intention.instance_of?(Intention)
    Binding.of_caller do |binding|
      intention.to_a(predicates, binding)
    end
  end
end
| YAGURA | ソフトウェア | 18:15 | comments(0) | trackbacks(0) |
スポンサーサイト
| スポンサードリンク | - | 18:15 | - | - |









http://yaglog.jugem.jp/trackback/36
      1
2345678
9101112131415
16171819202122
23242526272829
30      
<< April 2017 >>

このページの先頭へ