dummy_log_generator 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 38e90f1ce32f540d7c61384166fdfd4ff9f96848
4
- data.tar.gz: c12675bd60344e5f33781f02147462867a30a87e
3
+ metadata.gz: 6a76a35eb0df876125713ea8afd7d3128368e73b
4
+ data.tar.gz: e97dc9abc1fff91fcb1e4c6b5b8179b9c25cf596
5
5
  SHA512:
6
- metadata.gz: fdc71004c1590c96b72db467ac142da5482711171f0706c5236951489d865a8ce5656a4e3c85b4af819d86149168c705ac830ce95644395992c61ae17ad04e32
7
- data.tar.gz: 638c8ac586c1e18e72dee2143053657619092dfb6f679ff995d9f7b776a0357965757d452735c75e3e45194fc46be9f5f425adb9436217e05b67ac5a4d9dcf00
6
+ metadata.gz: 65200ca5573a8f275ee1dfd1c5869ce30d1e5840737ff55eefc5c45d90c0d9b7c2729976274e6d8a549183c6337d29c3484e2bbf9f4b1aa84e407752f9bd586a
7
+ data.tar.gz: 15921096adbdd0d1214a7a6afb0b9d29a74b5be39da3af8b4a0b01918597c671d903d044658fa98f7dfeca88289d7ad05e9efc9e007294e2392f4cf0cf2c4cab
data/.gitignore CHANGED
@@ -23,4 +23,6 @@ rdoc
23
23
  spec/reports
24
24
  test/tmp
25
25
  test/version_tmp
26
- tmp
26
+ dummy_log_generator.pid
27
+ dummy_log_generator.log
28
+
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ### 0.1.0
2
+
3
+ Enhancement:
4
+
5
+ * Support to output into a file (`output` option)
6
+ * No dependency on active_support
7
+ * Speed-up (Proc-based evaluation)
8
+ * Support parallel (`workers` option)
9
+
1
10
  ### 0.0.4
2
11
 
3
12
  Enhancement:
data/README.md CHANGED
@@ -27,6 +27,7 @@ Sample configuration is as follows:
27
27
  ```ruby
28
28
  # dummy_log_generator.conf
29
29
  configure 'sample' do
30
+ output dummy.log
30
31
  rate 500
31
32
  delimiter "\t"
32
33
  labeled true
@@ -40,7 +41,7 @@ configure 'sample' do
40
41
  end
41
42
  ```
42
43
 
43
- Running dummy_log_generator outputs like
44
+ Running dummy_log_generator outputs to `dummy.log` like
44
45
 
45
46
  ```
46
47
  id:422 time:[2013-11-19 02:34:58] level:INFO method:POST uri:/api/v1/textdata reqtime:3.9726677258569842 foobar:LFK6XV1N
@@ -52,6 +53,10 @@ id:424 time:[2013-11-19 02:34:58] level:WARN method:POST uri:/api/v1/textdata
52
53
 
53
54
  Following parameters for configuration is available
54
55
 
56
+ * output
57
+
58
+ Specify a filename to output, or IO object (STDOUT, STDERR)
59
+
55
60
  * rate
56
61
 
57
62
  Specify how many messages to generate per second. Default: 500 msgs / sec
@@ -88,10 +93,6 @@ You can specify following data types to your `field` parameters:
88
93
 
89
94
  * :string
90
95
 
91
- * :format
92
-
93
- You can specify a format of string as `%s`.
94
-
95
96
  * :any
96
97
 
97
98
  You can specify an array of strings, then the generator picks one from them randomly
@@ -143,9 +144,6 @@ There is a [fluent-plugin-dummydata-producer](https://github.com/tagomoris/fluen
143
144
  ## ToDO
144
145
 
145
146
  1. write tests
146
- 2. make it slim (remove active_support, etc)
147
- 3. outputs to a file (currently, outputs to STDOUT)
148
- 4. speed up (evaluate fields at only starting up)
149
147
 
150
148
  ## Contributing
151
149
 
@@ -1,8 +1,9 @@
1
1
  configure 'sample' do
2
+ # output "dummy_log_generator.log"
2
3
  rate 500
3
4
  delimiter "\t"
4
5
  labeled true
5
- field :id, type: :integer, countup: true
6
+ field :id, type: :integer, countup: true, format: "%04d"
6
7
  field :time, type: :datetime, format: "[%Y-%m-%d %H:%M:%S]", random: false
7
8
  field :level, type: :string, any: %w[DEBUG INFO WARN ERROR]
8
9
  field :method, type: :string, any: %w[GET POST PUT]
@@ -20,8 +20,6 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "thor"
22
22
  spec.add_dependency "serverengine"
23
- spec.add_dependency "active_support"
24
- spec.add_dependency "i18n"
25
23
 
26
24
  spec.add_development_dependency "bundler", "~> 1.3"
27
25
  spec.add_development_dependency "rake"
@@ -1,8 +1,6 @@
1
- require 'logger'
2
1
  require "dummy_log_generator/version"
3
2
  require "dummy_log_generator/error"
3
+ require "dummy_log_generator/setting"
4
4
  require "dummy_log_generator/generator"
5
- require "dummy_log_generator/formatter"
6
5
  require "dummy_log_generator/worker"
7
6
  require "dummy_log_generator/dsl"
8
-
@@ -1,39 +1,39 @@
1
1
  require 'thor'
2
2
  require 'dummy_log_generator'
3
- require 'active_support/core_ext'
3
+ require 'ext/hash/keys'
4
+ require 'ext/hash/except'
4
5
 
5
6
  module DummyLogGenerator
6
7
  class CLI < Thor
7
- class_option :config, :aliases => ["-c"], :type => :string, :default => 'dummy_log_generator.conf'
8
+ # options for serverengine
9
+ class_option :pid_path, :aliases => ["-p"], :type => :string, :default => 'dummy_log_generator.pid'
8
10
  default_command :start
9
11
 
10
12
  def initialize(args = [], opts = [], config = {})
11
13
  super(args, opts, config)
12
-
13
- @options = @options.dup # avoid frozen
14
- if options[:config] && File.exists?(options[:config])
15
- dsl = instance_eval(File.read(options[:config]), options[:config])
16
- @options[:generator] = dsl.generator
17
- @options[:formatter] = dsl.formatter
18
- @options[:rate] = dsl.config.rate
19
- end
20
14
  end
21
15
 
22
16
  desc "start", "Start a dummy_log_generator"
23
- option :require, :aliases => ["-r"], :type => :string
17
+ option :config, :aliases => ["-c"], :type => :string, :default => 'dummy_log_generator.conf'
18
+ # options for serverengine
24
19
  option :daemonize, :aliases => ["-d"], :type => :boolean
25
- option :module_name, :aliases => ["-m"], :type => :string, :default => 'DummyLogGenerator::Worker'
26
- # options for dummy_log_generator
27
- option :rate, :aliases => ["-i"], :type => :numeric
20
+ option :workers, :aliases => ["-w"], :type => :numeric
21
+ option :worker_type, :type => :string, :default => 'process'
28
22
  def start
29
- opts = @options.symbolize_keys.except(:require, :config, :module_name)
23
+ @options = @options.dup # avoid frozen
24
+ if options[:config] && File.exists?(options[:config])
25
+ dsl = instance_eval(File.read(options[:config]), options[:config])
26
+ @options[:setting] = dsl.setting
27
+ # options for serverengine
28
+ @options[:workers] ||= dsl.setting.workers
29
+ end
30
30
 
31
- se = ServerEngine.create(nil, @options["module_name"].constantize, opts)
31
+ opts = @options.symbolize_keys.except(:config)
32
+ se = ServerEngine.create(nil, DummyLogGenerator::Worker, opts)
32
33
  se.run
33
34
  end
34
35
 
35
36
  desc "stop", "Stops a dummy_log_generator"
36
- option :pid_path, :aliases => ["-p"], :type => :string
37
37
  def stop
38
38
  pid = File.read(@options["pid_path"]).to_i
39
39
 
@@ -46,7 +46,6 @@ module DummyLogGenerator
46
46
  end
47
47
 
48
48
  desc "graceful_stop", "Gracefully stops a dummy_log_generator"
49
- option :pid_path, :aliases => ["-p"], :type => :string
50
49
  def graceful_stop
51
50
  pid = File.read(@options["pid_path"]).to_i
52
51
 
@@ -59,7 +58,6 @@ module DummyLogGenerator
59
58
  end
60
59
 
61
60
  desc "restart", "Restarts a dummy_log_generator"
62
- option :pid_path, :aliases => ["-p"], :type => :string
63
61
  def restart
64
62
  pid = File.read(@options["pid_path"]).to_i
65
63
 
@@ -72,7 +70,6 @@ module DummyLogGenerator
72
70
  end
73
71
 
74
72
  desc "graceful_restart", "Graceful restarts a dummy_log_generator"
75
- option :pid_path, :aliases => ["-p"], :type => :string
76
73
  def graceful_restart
77
74
  pid = File.read(@options["pid_path"]).to_i
78
75
 
@@ -1,39 +1,33 @@
1
- module DummyLogGenerator
2
- class Config
3
- attr_accessor :rate
4
-
5
- def initiaize
6
- @rate = 500
7
- end
8
- end
9
- end
10
-
11
1
  module DummyLogGenerator
12
2
  class Dsl
13
- attr_reader :generator
14
- attr_reader :formatter
15
- attr_reader :config
3
+ attr_reader :setting
16
4
 
17
5
  def initialize
18
- @generator = Generator.new
19
- @formatter = Formatter.new
20
- @config = Config.new
6
+ @setting = Setting.new
21
7
  end
22
8
 
23
9
  def rate(rate)
24
- config.rate = rate
10
+ setting.rate = rate
11
+ end
12
+
13
+ def output(output)
14
+ setting.output = output
25
15
  end
26
16
 
27
17
  def field(name, opts)
28
- generator.fields[name] = opts
18
+ setting.fields[name] = opts
29
19
  end
30
20
 
31
21
  def delimiter(delimiter)
32
- formatter.delimiter = delimiter
22
+ setting.delimiter = delimiter
33
23
  end
34
24
 
35
25
  def labeled(labeled)
36
- formatter.labeled = labeled
26
+ setting.labeled = labeled
27
+ end
28
+
29
+ def workers(workers)
30
+ setting.workers = workers
37
31
  end
38
32
  end
39
33
  end
@@ -1,35 +1,45 @@
1
1
  module DummyLogGenerator
2
2
  class Generator
3
- attr_accessor :fields
4
- attr_reader :rand
3
+ def initialize(setting)
4
+ prepare_format_proc(setting.labeled, setting.delimiter)
5
+ prepare_field_procs(setting.fields)
6
+ end
5
7
 
6
- def initialize
7
- @fields = {}
8
- @rand = ::DummyLogGenerator::Random.new
8
+ def prepare_format_proc(labeled, delimiter)
9
+ @format_proc =
10
+ if labeled
11
+ Proc.new {|fields| fields.map {|key, val| "#{key}:#{val}" }.join(delimiter) }
12
+ else
13
+ Proc.new {|fields| fields.values.join(delimiter) }
14
+ end
9
15
  end
10
16
 
11
- def generate(prev_data = {})
12
- data = {}
17
+ def prepare_field_procs(fields)
18
+ rand = ::DummyLogGenerator::Random.new
19
+ @field_procs = {}
13
20
  fields.each do |key, opts|
14
21
  opts = opts.dup
15
22
  type = opts.delete(:type)
16
- opts[:prev] = prev_data[key]
17
- data[key] = case type
18
- when :datetime
19
- rand.datetime(opts)
20
- when :string
21
- rand.string(opts)
22
- when :integer
23
- rand.integer(opts)
24
- when :float
25
- rand.float(opts)
26
- else
27
- raise ConfigError.new(type)
28
- end
23
+ if rand.respond_to?(type)
24
+ @field_procs[key] = rand.send(type, opts)
25
+ else
26
+ raise ConfigError.new(type)
27
+ end
28
+ end
29
+ end
30
+
31
+ def generate(prev_data = {})
32
+ data = {}
33
+ @field_procs.each do |key, proc|
34
+ prev = prev_data[key] || -1
35
+ data[key] = proc.call(prev)
29
36
  end
30
37
  data
31
38
  end
32
- alias_method :gen, :generate
39
+
40
+ def format(fields)
41
+ @format_proc.call(fields)
42
+ end
33
43
  end
34
44
 
35
45
  class Random
@@ -38,59 +48,82 @@ module DummyLogGenerator
38
48
  @chars = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a # no symbols and multi-bytes for now
39
49
  end
40
50
 
41
- def string(format: nil, length: 8, any: nil, prev: nil, value: nil)
42
- string = if value
43
- value.to_s
44
- elsif any
45
- self.any(any)
46
- else
47
- Array.new(length){@chars[rand(@chars.size-1)]}.join
48
- end
49
- format ? sprintf(format, string) : string
51
+ def string(length: 8, any: nil, value: nil)
52
+ if value
53
+ string = value.to_s
54
+ Proc.new { string }
55
+ elsif any
56
+ Proc.new { self.any(any) }
57
+ else
58
+ Proc.new { Array.new(length){@chars[rand(@chars.size-1)]}.join }
59
+ end
50
60
  end
51
61
 
52
- def integer(format: nil, range: nil, countup: false, prev: nil, value: nil)
53
- integer = if value
54
- value.to_i
55
- elsif range
56
- self.range(range)
57
- elsif countup
58
- prev ||= -1
59
- prev.to_i + 1
60
- else
61
- rand(0..2,147,483,647)
62
- end
63
- format ? sprintf(format, integer) : integer
62
+ def integer(format: nil, range: nil, countup: false, value: nil)
63
+ if format
64
+ if value
65
+ integer = sprintf(format, value.to_i)
66
+ Proc.new { integer }
67
+ elsif range
68
+ Proc.new { sprintf(format, self.range(range)) }
69
+ elsif countup
70
+ Proc.new {|prev| sprintf(format, prev.to_i + 1) }
71
+ else
72
+ Proc.new { sprintf(format, rand(0..2,147,483,647)) }
73
+ end
74
+ else
75
+ if value
76
+ integer = value.to_i
77
+ Proc.new { integer }
78
+ elsif range
79
+ Proc.new { self.range(range) }
80
+ elsif countup
81
+ Proc.new {|prev| prev + 1 }
82
+ else
83
+ Proc.new { rand(0..2,147,483,647) }
84
+ end
85
+ end
64
86
  end
65
87
 
66
- def float(format: nil, range: nil, prev: nil, value: nil)
67
- float = if value
68
- value.to_f
69
- elsif range
70
- self.range(range)
71
- else
72
- r = rand(1..358)
73
- r * Math.cos(r) # cheat
74
- end
75
- format ? sprintf(format, float) : float
88
+ def float(format: nil, range: nil, value: nil)
89
+ if format
90
+ if value
91
+ float = value.to_f
92
+ Proc.new { sprintf(format, float) }
93
+ elsif range
94
+ Proc.new { sprintf(format, self.range(range)) }
95
+ else
96
+ Proc.new { r = rand(1..358); sprintf(format, r * Math.cos(r)) }
97
+ end
98
+ else
99
+ if value
100
+ float = value.to_f
101
+ Proc.new { float }
102
+ elsif range
103
+ Proc.new { self.range(range) }
104
+ else
105
+ Proc.new { r = rand(1..358); r * Math.cos(r) }
106
+ end
107
+ end
76
108
  end
77
109
 
78
- def datetime(format: "%Y-%m-%d %H:%M:%S.%3N", random: false, prev: nil, value: nil)
79
- time = if value
80
- value
81
- elsif random
82
- y = rand(1970..2037);
83
- m = rand(1..12);
84
- d = rand(1..27);
85
- h = rand(0..23);
86
- min = rand(0..59);
87
- s = rand(0..59);
88
- usec = rand(0..999999);
89
- Time.local(y, m, d, h, min, s, usec)
90
- else
91
- Time.now
92
- end
93
- time.strftime(format)
110
+ def datetime(format: "%Y-%m-%d %H:%M:%S.%3N", random: false, value: nil)
111
+ if value
112
+ Proc.new { value.sprintf(format) }
113
+ elsif random
114
+ Proc.new {
115
+ y = rand(1970..2037);
116
+ m = rand(1..12);
117
+ d = rand(1..27);
118
+ h = rand(0..23);
119
+ min = rand(0..59);
120
+ s = rand(0..59);
121
+ usec = rand(0..999999);
122
+ Time.local(y, m, d, h, min, s, usec)
123
+ }
124
+ else
125
+ Proc.new { Time.now }
126
+ end
94
127
  end
95
128
 
96
129
  def range(range)
@@ -0,0 +1,14 @@
1
+ module DummyLogGenerator
2
+ class Setting
3
+ attr_accessor :rate, :output, :labeled, :delimiter, :fields, :workers
4
+
5
+ def initialize
6
+ @rate = 500
7
+ @output = STDOUT
8
+ @labeled = true
9
+ @delimiter = "\t"
10
+ @fields = {}
11
+ @workers = 1
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module DummyLogGenerator
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -7,9 +7,16 @@ module DummyLogGenerator
7
7
  end
8
8
 
9
9
  def reload
10
- @rate = config[:rate]
11
- @formatter = config[:formatter]
12
- @generator = config[:generator]
10
+ @generator = Generator.new(config[:setting])
11
+ @rate = config[:setting].rate
12
+
13
+ output = config[:setting].output
14
+ if output.respond_to?(:write) and output.respond_to?(:close)
15
+ @output = output
16
+ else
17
+ @output = open(output, (File::WRONLY | File::APPEND | File::CREAT))
18
+ @output.sync = true
19
+ end
13
20
  end
14
21
 
15
22
  # thanks! ref. https://github.com/tagomoris/fluent-plugin-dummydata-producer/blob/a550fd4424f71cd9227e138c3c89f600ba40a0d5/lib/fluent/plugin/in_dummydata_producer.rb#L63
@@ -25,7 +32,7 @@ module DummyLogGenerator
25
32
  # ToDo: what if generation is slower than I/O?
26
33
  # We may should generate data and output in parallel
27
34
  prev_data = @generator.generate(prev_data)
28
- STDOUT.puts @formatter.format(prev_data)
35
+ @output.write "#{@generator.format(prev_data)}\n"
29
36
  end
30
37
  rate_count += batch_num
31
38
  sleep 0.1
@@ -35,6 +42,8 @@ module DummyLogGenerator
35
42
  sleep 0.04
36
43
  end
37
44
  end
45
+ ensure
46
+ @output.close
38
47
  end
39
48
 
40
49
  def stop
@@ -0,0 +1,15 @@
1
+ class Hash
2
+ # Return a hash that includes everything but the given keys. This is useful for
3
+ # limiting a set of parameters to everything but a few known toggles:
4
+ #
5
+ # @person.update(params[:person].except(:admin))
6
+ def except(*keys)
7
+ dup.except!(*keys)
8
+ end
9
+
10
+ # Replaces the hash without the given keys.
11
+ def except!(*keys)
12
+ keys.each { |key| delete(key) }
13
+ self
14
+ end
15
+ end
@@ -0,0 +1,138 @@
1
+ class Hash
2
+ # Return a new hash with all keys converted using the block operation.
3
+ #
4
+ # hash = { name: 'Rob', age: '28' }
5
+ #
6
+ # hash.transform_keys{ |key| key.to_s.upcase }
7
+ # # => {"NAME"=>"Rob", "AGE"=>"28"}
8
+ def transform_keys
9
+ result = {}
10
+ each_key do |key|
11
+ result[yield(key)] = self[key]
12
+ end
13
+ result
14
+ end
15
+
16
+ # Destructively convert all keys using the block operations.
17
+ # Same as transform_keys but modifies +self+.
18
+ def transform_keys!
19
+ keys.each do |key|
20
+ self[yield(key)] = delete(key)
21
+ end
22
+ self
23
+ end
24
+
25
+ # Return a new hash with all keys converted to strings.
26
+ #
27
+ # hash = { name: 'Rob', age: '28' }
28
+ #
29
+ # hash.stringify_keys
30
+ # # => {"name"=>"Rob", "age"=>"28"}
31
+ def stringify_keys
32
+ transform_keys{ |key| key.to_s }
33
+ end
34
+
35
+ # Destructively convert all keys to strings. Same as
36
+ # +stringify_keys+, but modifies +self+.
37
+ def stringify_keys!
38
+ transform_keys!{ |key| key.to_s }
39
+ end
40
+
41
+ # Return a new hash with all keys converted to symbols, as long as
42
+ # they respond to +to_sym+.
43
+ #
44
+ # hash = { 'name' => 'Rob', 'age' => '28' }
45
+ #
46
+ # hash.symbolize_keys
47
+ # # => {"name"=>"Rob", "age"=>"28"}
48
+ def symbolize_keys
49
+ transform_keys{ |key| key.to_sym rescue key }
50
+ end
51
+ alias_method :to_options, :symbolize_keys
52
+
53
+ # Destructively convert all keys to symbols, as long as they respond
54
+ # to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
55
+ def symbolize_keys!
56
+ transform_keys!{ |key| key.to_sym rescue key }
57
+ end
58
+ alias_method :to_options!, :symbolize_keys!
59
+
60
+ # Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError
61
+ # on a mismatch. Note that keys are NOT treated indifferently, meaning if you
62
+ # use strings for keys but assert symbols as keys, this will fail.
63
+ #
64
+ # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years"
65
+ # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name"
66
+ # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
67
+ def assert_valid_keys(*valid_keys)
68
+ valid_keys.flatten!
69
+ each_key do |k|
70
+ raise ArgumentError.new("Unknown key: #{k}") unless valid_keys.include?(k)
71
+ end
72
+ end
73
+
74
+ # Return a new hash with all keys converted by the block operation.
75
+ # This includes the keys from the root hash and from all
76
+ # nested hashes.
77
+ #
78
+ # hash = { person: { name: 'Rob', age: '28' } }
79
+ #
80
+ # hash.deep_transform_keys{ |key| key.to_s.upcase }
81
+ # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
82
+ def deep_transform_keys(&block)
83
+ result = {}
84
+ each do |key, value|
85
+ result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
86
+ end
87
+ result
88
+ end
89
+
90
+ # Destructively convert all keys by using the block operation.
91
+ # This includes the keys from the root hash and from all
92
+ # nested hashes.
93
+ def deep_transform_keys!(&block)
94
+ keys.each do |key|
95
+ value = delete(key)
96
+ self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
97
+ end
98
+ self
99
+ end
100
+
101
+ # Return a new hash with all keys converted to strings.
102
+ # This includes the keys from the root hash and from all
103
+ # nested hashes.
104
+ #
105
+ # hash = { person: { name: 'Rob', age: '28' } }
106
+ #
107
+ # hash.deep_stringify_keys
108
+ # # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
109
+ def deep_stringify_keys
110
+ deep_transform_keys{ |key| key.to_s }
111
+ end
112
+
113
+ # Destructively convert all keys to strings.
114
+ # This includes the keys from the root hash and from all
115
+ # nested hashes.
116
+ def deep_stringify_keys!
117
+ deep_transform_keys!{ |key| key.to_s }
118
+ end
119
+
120
+ # Return a new hash with all keys converted to symbols, as long as
121
+ # they respond to +to_sym+. This includes the keys from the root hash
122
+ # and from all nested hashes.
123
+ #
124
+ # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
125
+ #
126
+ # hash.deep_symbolize_keys
127
+ # # => {:person=>{:name=>"Rob", :age=>"28"}}
128
+ def deep_symbolize_keys
129
+ deep_transform_keys{ |key| key.to_sym rescue key }
130
+ end
131
+
132
+ # Destructively convert all keys to symbols, as long as they respond
133
+ # to +to_sym+. This includes the keys from the root hash and from all
134
+ # nested hashes.
135
+ def deep_symbolize_keys!
136
+ deep_transform_keys!{ |key| key.to_sym rescue key }
137
+ end
138
+ end
@@ -0,0 +1,42 @@
1
+ class Hash
2
+ # Slice a hash to include only the given keys. This is useful for
3
+ # limiting an options hash to valid keys before passing to a method:
4
+ #
5
+ # def search(criteria = {})
6
+ # criteria.assert_valid_keys(:mass, :velocity, :time)
7
+ # end
8
+ #
9
+ # search(options.slice(:mass, :velocity, :time))
10
+ #
11
+ # If you have an array of keys you want to limit to, you should splat them:
12
+ #
13
+ # valid_keys = [:mass, :velocity, :time]
14
+ # search(options.slice(*valid_keys))
15
+ def slice(*keys)
16
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
17
+ keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
18
+ end
19
+
20
+ # Replaces the hash with only the given keys.
21
+ # Returns a hash containing the removed key/value pairs.
22
+ #
23
+ # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
24
+ # # => {:c=>3, :d=>4}
25
+ def slice!(*keys)
26
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
27
+ omit = slice(*self.keys - keys)
28
+ hash = slice(*keys)
29
+ hash.default = default
30
+ hash.default_proc = default_proc if default_proc
31
+ replace(hash)
32
+ omit
33
+ end
34
+
35
+ # Removes and returns the key/value pairs matching the given keys.
36
+ #
37
+ # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
38
+ # { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1}
39
+ def extract!(*keys)
40
+ keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
41
+ end
42
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dummy_log_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sonots
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-18 00:00:00.000000000 Z
11
+ date: 2013-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -38,34 +38,6 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: active_support
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: i18n
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - '>='
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
41
  - !ruby/object:Gem::Dependency
70
42
  name: bundler
71
43
  requirement: !ruby/object:Gem::Requirement
@@ -158,10 +130,13 @@ files:
158
130
  - lib/dummy_log_generator/cli.rb
159
131
  - lib/dummy_log_generator/dsl.rb
160
132
  - lib/dummy_log_generator/error.rb
161
- - lib/dummy_log_generator/formatter.rb
162
133
  - lib/dummy_log_generator/generator.rb
134
+ - lib/dummy_log_generator/setting.rb
163
135
  - lib/dummy_log_generator/version.rb
164
136
  - lib/dummy_log_generator/worker.rb
137
+ - lib/ext/hash/except.rb
138
+ - lib/ext/hash/keys.rb
139
+ - lib/ext/hash/slice.rb
165
140
  homepage: https://github.com/sonots/dummy_log_generator
166
141
  licenses:
167
142
  - MIT
@@ -1,18 +0,0 @@
1
- module DummyLogGenerator
2
- class Formatter
3
- attr_accessor :labeled, :delimiter
4
-
5
- def initialize
6
- @labeled = true
7
- @delimiter = "\t"
8
- end
9
-
10
- def format(fields)
11
- if labeled
12
- fields.map {|key, val| "#{key}:#{val}" }.join(delimiter)
13
- else
14
- fields.values.join(delimiter)
15
- end
16
- end
17
- end
18
- end