lib/rantly/generator.rb in rantly-1.2.0 vs lib/rantly/generator.rb in rantly-2.0.0

- old
+ new

@@ -1,7 +1,6 @@ class Rantly - class << self attr_writer :default_size def singleton @singleton ||= Rantly.new @singleton @@ -9,80 +8,79 @@ def default_size @default_size || 6 end - def each(n,limit=10,&block) - gen.each(n,limit,&block) + def each(n, limit = 10, &block) + gen.each(n, limit, &block) end - def map(n,limit=10,&block) - gen.map(n,limit,&block) + def map(n, limit = 10, &block) + gen.map(n, limit, &block) end - def value(limit=10,&block) - gen.value(limit,&block) + def value(limit = 10, &block) + gen.value(limit, &block) end def gen - self.singleton + singleton end end class GuardFailure < RuntimeError end class TooManyTries < RuntimeError - def initialize(limit,nfailed) + def initialize(limit, nfailed) @limit = limit @nfailed = nfailed end def tries @nfailed end - def to_s - "Exceed gen limit #{@limit}: #{@nfailed} failed guards" - end + attr_reader :limit end # limit attempts to 10 times of how many things we want to generate - def each(n,limit=10,&block) - generate(n,limit,block) + def each(n, limit = 10, &block) + generate(n, limit, block) end - def map(n,limit=10,&block) + def map(n, limit = 10, &block) acc = [] - generate(n,limit,block) do |val| + generate(n, limit, block) do |val| acc << val end acc end - def value(limit=10,&block) - generate(1,limit,block) do |val| + def value(limit = 10, &block) + generate(1, limit, block) do |val| return val end end - def generate(n,limit_arg,gen_block,&handler) + def generate(n, limit_arg, gen_block, &handler) limit = n * limit_arg nfailed = 0 nsuccess = 0 while nsuccess < n - raise TooManyTries.new(limit_arg*n,nfailed) if limit < 0 + raise TooManyTries.new(limit_arg * n, nfailed) if limit.zero? + begin - val = self.instance_eval(&gen_block) + val = instance_eval(&gen_block) rescue GuardFailure nfailed += 1 limit -= 1 next end nsuccess += 1 limit -= 1 - handler.call(val) if handler + yield(val) if handler end end attr_accessor :classifiers @@ -98,144 +96,144 @@ def classify(classifier) @classifiers[classifier] += 1 end def guard(test) - unless test - raise GuardFailure.new - else - true - end + return true if test + + raise GuardFailure end def size @size || Rantly.default_size end - def sized(n,&block) - raise "size needs to be greater than zero" if n < 0 + def sized(n, &block) + raise 'size needs to be greater than zero' if n.negative? + old_size = @size @size = n - r = self.instance_eval(&block) + r = instance_eval(&block) @size = old_size - return r + r end # wanna avoid going into Bignum when calling range with these. INTEGER_MAX = (2**(0.size * 8 - 2) - 1) / 2 - INTEGER_MIN = -(INTEGER_MAX) - def integer(limit=nil) + INTEGER_MIN = -INTEGER_MAX + def integer(limit = nil) case limit when Range hi = limit.end lo = limit.begin when Integer - raise "n should be greater than zero" if limit < 0 - hi, lo = limit, -limit + raise 'n should be greater than zero' if limit.negative? + + hi = limit + lo = -limit else - hi, lo = INTEGER_MAX, INTEGER_MIN + hi = INTEGER_MAX + lo = INTEGER_MIN end - range(lo,hi) + range(lo, hi) end def positive_integer range(0) end - def float(distribution=nil, params={}) + def float(distribution = nil, params = {}) case distribution when :normal params[:center] ||= 0 params[:scale] ||= 1 - raise "The distribution scale should be greater than zero" unless params[:scale] > 0 + raise 'The distribution scale should be greater than zero' if params[:scale].negative? + # Sum of 6 draws from a uniform distribution give as a draw of a normal # distribution centered in 3 (central limit theorem). - ([rand, rand, rand, rand, rand, rand].reduce(0, :+) - 3) * params[:scale] + params[:center] + ([rand, rand, rand, rand, rand, rand].sum - 3) * params[:scale] + params[:center] else rand end end - def range(lo=nil,hi=nil) - lo ||= INTEGER_MIN - hi ||= INTEGER_MAX - rand(hi+1-lo) + lo + def range(lo = INTEGER_MIN, hi = INTEGER_MAX) + rand(lo..hi) end - def call(gen,*args) + def call(gen, *args) case gen when Symbol - return self.send(gen,*args) + send(gen, *args) when Array - raise "empty array" if gen.empty? - return self.send(gen[0],*gen[1..-1]) + raise 'empty array' if gen.empty? + + send(gen[0], *gen[1..-1]) when Proc - return self.instance_eval(&gen) + instance_eval(&gen) else raise "don't know how to call type: #{gen}" end end def branch(*gens) - self.call(choose(*gens)) + call(choose(*gens)) end def choose(*vals) - vals[range(0,vals.length-1)] + vals[range(0, vals.length - 1)] if vals.length.positive? end def literal(value) value end def boolean - range(0,1) == 0 ? true : false + range(0, 1).zero? end def freq(*pairs) pairs = pairs.map do |pair| case pair when Symbol, String, Proc - [1,pair] + [1, pair] when Array - unless pair.first.is_a?(Integer) - [1] + pair - else + if pair.first.is_a?(Integer) pair + else + [1] + pair end end end - total = pairs.inject(0) { |sum,p| sum + p.first } - raise(RuntimeError, "Illegal frequency:#{pairs.inspect}") if total == 0 - pos = range(1,total) + total = pairs.inject(0) { |sum, p| sum + p.first } + raise("Illegal frequency:#{pairs.inspect}") if total.zero? + + pos = range(1, total) pairs.each do |p| weight, gen, *args = p - if pos <= p[0] - return self.call(gen,*args) - else - pos -= weight - end + return call(gen, *args) if pos <= p[0] + + pos -= weight end end - def array(n=self.size,&block) - n.times.map { self.instance_eval(&block) } + def array(n = size, &block) + n.times.map { instance_eval(&block) } end - def dict(n=self.size,&block) + def dict(n = size, &block) h = {} each(n) do - k,v = instance_eval(&block) - h[k] = v if guard(!h.has_key?(k)) + k, v = instance_eval(&block) + h[k] = v if guard(!h.key?(k)) end h end module Chars - class << self - ASCII = (0..127).to_a.each_with_object("") { |i, obj| obj << i } + ASCII = (0..127).to_a.each_with_object('') { |i, obj| obj << i } def of(regexp) ASCII.scan(regexp).to_a.map! { |char| char[0].ord } end end @@ -252,43 +250,37 @@ SPACE = Chars.of(/[[:space:]]/) UPPER = Chars.of(/[[:upper:]]/) XDIGIT = Chars.of(/[[:xdigit:]]/) ASCII = Chars.of(/./) - CLASSES = { - :alnum => ALNUM, - :alpha => ALPHA, - :blank => BLANK, - :cntrl => CNTRL, - :digit => DIGIT, - :graph => GRAPH, - :lower => LOWER, - :print => PRINT, - :punct => PUNCT, - :space => SPACE, - :upper => UPPER, - :xdigit => XDIGIT, - :ascii => ASCII, - } - + alnum: ALNUM, + alpha: ALPHA, + blank: BLANK, + cntrl: CNTRL, + digit: DIGIT, + graph: GRAPH, + lower: LOWER, + print: PRINT, + punct: PUNCT, + space: SPACE, + upper: UPPER, + xdigit: XDIGIT, + ascii: ASCII + }.freeze end - def string(char_class=:print) + def string(char_class = :print) chars = case char_class when Regexp Chars.of(char_class) when Symbol Chars::CLASSES[char_class] end - raise "bad arg" unless chars + raise 'bad arg' unless chars - char_strings = chars.map { |c| c.chr } + char_strings = chars.map(&:chr) str = Array.new(size) - current_index = 0 - while current_index < size - str[current_index] = char_strings.sample - current_index += 1 - end + size.times { |i| str[i] = char_strings.sample } str.join end end