bioinform 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -14,5 +14,4 @@ rdoc
14
14
  spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
- tmp
18
- TODO.txt
17
+ tmp
data/TODO.txt ADDED
@@ -0,0 +1,18 @@
1
+ Create Collection class. Rewrite MACRO-APE to use this class.
2
+
3
+ Create CLI-apps:
4
+ -- to merge many files(or whole folder) to a Collection
5
+
6
+ Make Parsers to be switcheable in runtime so that one could parse string composed of two motifs in different formats.
7
+
8
+ Decide:
9
+ -- Whether PPM should have `words_count`/`weight`?
10
+ PPM format such that parser got both matrix and count (if PPM have `word_count`)
11
+ -- can_parse?
12
+ -- Whether to cache suffices: cache :best_suffix, obsolete: [:discrete!, :background!, ...]
13
+
14
+ Specs
15
+ -- PM#== (!)
16
+ -- PWM#probabilities, #score_variance, #gauss_estimation
17
+ -- pcm2pwm
18
+ -- split_motifs
data/bin/pcm2pwm ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bioinform/cli/pcm2pwm'
4
+ Bioinform::CLI::PCM2PWM.main(ARGV)
data/bin/split_motifs ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bioinform/cli/split_motifs'
4
+ Bioinform::CLI::SplitMotifs.main(ARGV)
@@ -0,0 +1,47 @@
1
+ require 'bioinform'
2
+ require 'docopt'
3
+ require 'shellwords'
4
+
5
+ module Bioinform
6
+ module CLI
7
+ module PCM2PWM
8
+ def self.main(argv)
9
+ doc = <<-DOCOPT
10
+ PCM to PWM converter.
11
+ It transforms files with PCMs into files with PWMs. Folder for resulting files to save files can be specified. Resulting PWM files have the same name as original file but have another extension (.pwm by default).
12
+ When filelist is empty, it's obtained from STDIN. One can use it: `ls -b pcm_folder/*.pcm | pcm2pwm` (ls -b option escape spaces in filenames)
13
+
14
+ Usage:
15
+ #{__FILE__} [options] [<pcm-files>...]
16
+
17
+ Options:
18
+ -h --help Show this screen.
19
+ -e --extension EXT Extension of output files [default: pwm]
20
+ -f --folder FOLDER Where to save output files [default: .]
21
+ DOCOPT
22
+
23
+ options = Docopt::docopt(doc, argv: argv)
24
+
25
+ if options['<pcm-files>'].empty?
26
+ filelist = $stdin.read.shellsplit
27
+ else
28
+ filelist = options['<pcm-files>']
29
+ end
30
+
31
+ folder = options['--folder']
32
+ Dir.mkdir(folder) unless Dir.exist?(folder)
33
+
34
+ filelist.each do |pcm_filename|
35
+ pwm = Bioinform::PCM.new( File.read(pcm_filename) ).to_pwm
36
+ File.open(Bioinform::CLI.output_filename(pcm_filename, options['--extension'], folder), 'w') do |f|
37
+ f.puts pwm
38
+ end
39
+ end
40
+
41
+ rescue Docopt::Exit => e
42
+ puts e.message
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,46 @@
1
+ require 'bioinform'
2
+ require 'docopt'
3
+
4
+ module Bioinform
5
+ module CLI
6
+ module SplitMotifs
7
+
8
+ def self.main(argv)
9
+ doc = <<-DOCOPT
10
+ Motif splitter.
11
+ It get a file with a set of motifs and splits it into motifs according to their names.
12
+
13
+ Usage:
14
+ #{__FILE__} [options] <collection-file>
15
+
16
+ Options:
17
+ -h --help Show this screen.
18
+ -m --data-model MODEL Data model: PM, PCM, PPM or PWM [default: PM]
19
+ -e --extension EXT Extension of output files (by default it's based on data model)
20
+ -f --folder FOLDER Where to save output files [default: .]
21
+ DOCOPT
22
+
23
+ options = Docopt::docopt(doc, argv: argv)
24
+
25
+ folder = options['--folder']
26
+ Dir.mkdir(folder) unless Dir.exist?(folder)
27
+
28
+ data_model = Bioinform.const_get(options['--data-model'].upcase)
29
+ extension = options['--extension'] || options['--data-model'].downcase
30
+
31
+ collection_filename = options['<collection-file>']
32
+ raise "File #{collection_filename} not exist" unless File.exist? collection_filename
33
+ input = File.read(collection_filename)
34
+
35
+ data_model.choose_parser(input).split_on_motifs(input, data_model).each do |motif|
36
+ File.open(File.join(folder, "#{motif.name}.#{extension}"), 'w') do |f|
37
+ f.puts motif
38
+ end
39
+ end
40
+ rescue Docopt::Exit => e
41
+ puts e.message
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,7 @@
1
+ module Bioinform
2
+ module CLI
3
+ def self.output_filename(input_filename, extension, folder)
4
+ File.join(folder, File.basename(input_filename, File.extname(input_filename)) + ".#{extension}")
5
+ end
6
+ end
7
+ end
@@ -1,7 +1,6 @@
1
1
  require 'bioinform/support'
2
- require 'bioinform/data_models/pm'
3
- require 'bioinform/data_models/ppm'
4
- require 'bioinform/data_models/pwm'
2
+ require 'bioinform/data_models'
3
+
5
4
  module Bioinform
6
5
  class PCM < PM
7
6
  def count
@@ -32,9 +32,9 @@ module Bioinform
32
32
  def self.valid_matrix?(matrix)
33
33
  matrix.is_a?(Array) &&
34
34
  ! matrix.empty? &&
35
- matrix.all?(&:is_a?.(Array)) &&
35
+ matrix.all?{|pos| pos.is_a?(Array)} &&
36
36
  matrix.all?{|pos| pos.size == 4} &&
37
- matrix.all?(&:all?.(&:is_a?.(Numeric)))
37
+ matrix.all?{|pos| pos.all?{|el| el.is_a?(Numeric)}}
38
38
  rescue
39
39
  false
40
40
  end
@@ -56,22 +56,37 @@ module Bioinform
56
56
  end
57
57
  alias_method :size, :length
58
58
 
59
- def to_s(with_name = true)
60
- matrix_str = each_position.map(&:join.("\t")).join("\n")
61
- if with_name && @name
59
+ def to_s(options = {})
60
+ default_options = {with_name: true, letters_as_rows: false}
61
+ options = default_options.merge(options)
62
+ if options[:letters_as_rows]
63
+ hsh = to_hash
64
+ matrix_str = [:A,:C,:G,:T].collect{|letter| "#{letter}|" + hsh[letter].join("\t")}.join("\n")
65
+ else
66
+ matrix_str = each_position.map{|pos| pos.join("\t")}.join("\n")
67
+ end
68
+
69
+ if options[:with_name] && @name
62
70
  @name + "\n" + matrix_str
63
71
  else
64
72
  matrix_str
65
73
  end
66
74
  end
67
75
 
68
- def pretty_string(with_name = true)
76
+ def pretty_string(options = {})
77
+ default_options = {with_name: true, letters_as_rows: false}
78
+
79
+ return to_s(options) if options[:letters_as_rows]
80
+
81
+ options = default_options.merge(options)
69
82
  header = %w{A C G T}.map{|el| el.rjust(4).ljust(7)}.join + "\n"
70
83
  matrix_rows = each_position.map do |position|
71
84
  position.map{|el| el.round(3).to_s.rjust(6)}.join(' ')
72
85
  end
86
+
73
87
  matrix_str = matrix_rows.join("\n")
74
- if with_name && @name
88
+
89
+ if options[:with_name] && @name
75
90
  @name + "\n" + header + matrix_str
76
91
  else
77
92
  header + matrix_str
@@ -80,7 +95,7 @@ module Bioinform
80
95
 
81
96
  def to_hash
82
97
  hsh = %w{A C G T}.each_with_index.collect_hash do |letter, letter_index|
83
- [ letter, @matrix.map(&:at.(letter_index)) ]
98
+ [ letter, @matrix.map{|pos| pos[letter_index]} ]
84
99
  end
85
100
  hsh.with_indifferent_access
86
101
  end
@@ -1,5 +1,5 @@
1
1
  require 'bioinform/support'
2
- require 'bioinform/data_models/pm'
2
+ require 'bioinform/data_models'
3
3
 
4
4
  module Bioinform
5
5
  class PPM < PM
@@ -1,5 +1,5 @@
1
1
  require 'bioinform/support'
2
- require 'bioinform/data_models/pm'
2
+ require 'bioinform/data_models'
3
3
  module Bioinform
4
4
  class PWM < PM
5
5
  def score_mean
@@ -2,7 +2,8 @@ require 'bioinform/parsers'
2
2
 
3
3
  require 'bioinform/data_models/pm'
4
4
  require 'bioinform/data_models/pcm'
5
- require 'bioinform/data_models/pwm'
6
5
  require 'bioinform/data_models/ppm'
6
+ require 'bioinform/data_models/pwm'
7
+
7
8
  #require 'bioinform/data_models/iupac_word'
8
9
  #require 'bioinform/data_models/iupac_wordset'
@@ -27,6 +27,10 @@ module Bioinform
27
27
  parse! rescue nil
28
28
  end
29
29
 
30
+ def self.choose(input, data_model = PM)
31
+ data_model.choose_parser(input).new(input)
32
+ end
33
+
30
34
  def self.parse!(*input)
31
35
  self.new(*input).parse!
32
36
  end
@@ -4,7 +4,7 @@ require 'bioinform/parsers/parser'
4
4
 
5
5
  module Bioinform
6
6
  class StringParser < Parser
7
- attr_reader :scanner
7
+ attr_reader :scanner, :row_acgt_markers
8
8
  def initialize(input)
9
9
  raise ArgumentError unless input.is_a?(String)
10
10
  super
@@ -20,7 +20,7 @@ module Bioinform
20
20
  end
21
21
 
22
22
  def row_pat
23
- /(?<row>(#{number_pat} )*#{number_pat})\n?/
23
+ /([ACGT]\s*[:|]?\s*)?(?<row>(#{number_pat} )*#{number_pat})\n?/
24
24
  end
25
25
 
26
26
  def scan_row
@@ -43,16 +43,23 @@ module Bioinform
43
43
 
44
44
  def parse_matrix
45
45
  matrix = []
46
+ @row_acgt_markers = true if scanner.check(/A.*\nC.*\nG.*\nT.*\n?/)
46
47
  while row_string = scan_row
47
48
  matrix << split_row(row_string)
48
49
  end
49
50
  matrix
50
51
  end
51
52
 
53
+ def parse_acgt_header
54
+ scanner.scan(/A\s*C\s*G\s*T\s*\n/i)
55
+ end
56
+
52
57
  def parse!
53
58
  scan_any_spaces
54
59
  name = parse_name
60
+ parse_acgt_header
55
61
  matrix = parse_matrix
62
+ matrix = matrix.transpose if row_acgt_markers
56
63
  Parser.parse!(matrix).merge(name: name)
57
64
  end
58
65
 
@@ -80,6 +87,5 @@ module Bioinform
80
87
  def self.split_on_motifs(input, pm_klass = PM)
81
88
  split(input).map{|el| pm_klass.new(el)}
82
89
  end
83
-
84
90
  end
85
91
  end
@@ -1,13 +1,10 @@
1
1
  require 'active_support/core_ext/string/filters'
2
2
  require 'active_support/core_ext/hash/indifferent_access'
3
3
 
4
- require 'bioinform/support/callable_symbol'
5
4
  require 'bioinform/support/collect_hash'
6
5
  require 'bioinform/support/delete_many'
7
- require 'bioinform/support/has_keys'
8
6
  require 'bioinform/support/multiline_squish'
9
7
  require 'bioinform/support/same_by'
10
- require 'bioinform/support/yaml_dump_file'
11
8
  require 'bioinform/support/inverf'
12
9
  require 'bioinform/support/deep_dup'
13
10
 
@@ -1,3 +1,3 @@
1
1
  module Bioinform
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
data/lib/bioinform.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'bioinform/version'
2
2
  require 'bioinform/support'
3
+ require 'bioinform/parsers'
3
4
  require 'bioinform/data_models'
5
+ require 'bioinform/cli'
4
6
 
5
7
  module Bioinform
6
8
  # Your code goes here...
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+ require 'bioinform/cli'
3
+
4
+ describe Bioinform::CLI do
5
+ describe '::output_filename' do
6
+ it 'should change extension and folder' do
7
+ Bioinform::CLI.output_filename('test.pcm', 'pwm', '.').should == './test.pwm'
8
+ Bioinform::CLI.output_filename('test.pcm', 'pat', 'pwm_folder').should == 'pwm_folder/test.pat'
9
+ Bioinform::CLI.output_filename('pcm/test.pcm', 'pat', 'pwm_folder').should == 'pwm_folder/test.pat'
10
+ Bioinform::CLI.output_filename('test.pcm', 'pat', '../pwm_folder').should == '../pwm_folder/test.pat'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'bioinform/cli/pcm2pwm'
3
+
4
+ describe Bioinform::CLI::PCM2PWM do
5
+
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'bioinform/cli/split_motifs'
3
+
4
+ describe Bioinform::CLI::SplitMotifs do
5
+
6
+ end
@@ -34,7 +34,12 @@ module Bioinform
34
34
  @pm.to_s.should == "Stub name\n1\t2\t3\t4\n1\t4\t5\t6.5"
35
35
  end
36
36
  it 'should not return a name if argument is set to false' do
37
- @pm.to_s(false).should == "1\t2\t3\t4\n1\t4\t5\t6.5"
37
+ @pm.to_s(with_name: false).should == "1\t2\t3\t4\n1\t4\t5\t6.5"
38
+ end
39
+ end
40
+ context 'in letters_as_rows mode' do
41
+ it 'should print matrix with row-markers' do
42
+ @pm.to_s(letters_as_rows: true).should == "A|1\t1\nC|2\t4\nG|3\t5\nT|4\t6.5"
38
43
  end
39
44
  end
40
45
  end
@@ -62,7 +67,7 @@ module Bioinform
62
67
  @pm.pretty_string.should match(/MyName\n/)
63
68
  end
64
69
  it 'should not contain name if parameter `with_name` is false' do
65
- @pm.pretty_string(false).should_not match(/MyName\n/)
70
+ @pm.pretty_string(with_name: false).should_not match(/MyName\n/)
66
71
  end
67
72
  end
68
73
  context 'without name specified' do
@@ -71,7 +76,13 @@ module Bioinform
71
76
  end
72
77
  it 'should not contain name whether parameter `with_name` is or isn\'t false' do
73
78
  @pm.pretty_string.should_not match(/MyName\n/)
74
- @pm.pretty_string(false).should_not match(/MyName\n/)
79
+ @pm.pretty_string(with_name: false).should_not match(/MyName\n/)
80
+ end
81
+ end
82
+ context 'in letters_as_rows mode' do
83
+ it 'should print matrix with row-markers as to_s do' do
84
+ @pm = PM.new( [[1.1,2.22,3.333,4.4444],[5.5,6.66,7.777,8.8888]] )
85
+ @pm.pretty_string(letters_as_rows: true).should == @pm.to_s(letters_as_rows: true)
75
86
  end
76
87
  end
77
88
  end
@@ -28,6 +28,19 @@ module Bioinform
28
28
  end
29
29
  end
30
30
 
31
+ context '::choose' do
32
+ it 'should create parser of appropriate type' do
33
+ Parser.choose([[1,2,3,4],[5,6,7,8]]).should be_kind_of(Parser)
34
+ Parser.choose([[1,2,3,4],[5,6,7,8]]).input.should == [[1,2,3,4],[5,6,7,8]]
35
+ Parser.choose(matrix: [[1,2,3,4],[5,6,7,8]], name: 'Name').should be_kind_of(TrivialParser)
36
+ Parser.choose(matrix: [[1,2,3,4],[5,6,7,8]], name: 'Name').input.should == {matrix: [[1,2,3,4],[5,6,7,8]], name: 'Name'}
37
+ Parser.choose("1 2 3 4\n5 6 7 8").should be_kind_of(StringParser)
38
+ Parser.choose("1 2 3 4\n5 6 7 8").input.should == "1 2 3 4\n5 6 7 8"
39
+ end
40
+
41
+ end
42
+
43
+
31
44
  context '::normalize_hash_keys' do
32
45
  it 'should convert both symbolic and string keys, in both upcase and downcase to symbolic upcases' do
33
46
  Parser.normalize_hash_keys( {a: 1, C: 2, 'g' => 3, 'T' => 4} ).should == {A: 1, C: 2, G: 3, T: 4}
@@ -79,7 +79,25 @@ module Bioinform
79
79
  matrix: [[1,2,3,4],[5,6,7,8]] },
80
80
 
81
81
  'string with windows crlf' => {input: "1 2 3 4\r\n5 6 7 8",
82
- matrix: [[1,2,3,4],[5,6,7,8]] }
82
+ matrix: [[1,2,3,4],[5,6,7,8]] },
83
+
84
+ 'Nx4 string with acgt-header' => {input: "A C G T\n1 2 3 4\n5 6 7 8",
85
+ matrix: [[1,2,3,4],[5,6,7,8]] },
86
+
87
+ 'Nx4 string with name and acgt-header' => {input: "Name\nA C G T\n1 2 3 4\n5 6 7 8",
88
+ matrix: [[1,2,3,4],[5,6,7,8]], name: 'Name'},
89
+
90
+ 'Nx4 string with acgt-row-markers' => {input: "A 1 5\nC : 2 6\nG3 7\nT |4 8",
91
+ matrix: [[1,2,3,4],[5,6,7,8]] },
92
+
93
+ '4x4 string with acgt-header' => {input: "A C G T\n1 2 3 4\n5 6 7 8\n0 0 0 0\n2 2 2 2",
94
+ matrix: [[1,2,3,4],[5,6,7,8],[0,0,0,0],[2,2,2,2]] },
95
+
96
+ '4x4 string with acgt-row-markers' => {input: "A|1 2 3 4\nC|5 6 7 8\nG|0 0 0 0\nT|2 2 2 2",
97
+ matrix: [[1,5,0,2],[2,6,0,2],[3,7,0,2],[4,8,0,2]] },
98
+
99
+ '4x4 string with name and acgt-row-markers' => {input: "Name\nA:1 2 3 4\nC:5 6 7 8\nG:0 0 0 0\nT:2 2 2 2",
100
+ matrix: [[1,5,0,2],[2,6,0,2],[3,7,0,2],[4,8,0,2]], name: 'Name' }
83
101
  }
84
102
 
85
103
  bad_cases = {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bioinform
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-01 00:00:00.000000000 Z
12
+ date: 2012-09-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -46,7 +46,9 @@ dependencies:
46
46
  description: A bunch of useful classes for bioinformatics
47
47
  email:
48
48
  - prijutme4ty@gmail.com
49
- executables: []
49
+ executables:
50
+ - pcm2pwm
51
+ - split_motifs
50
52
  extensions: []
51
53
  extra_rdoc_files: []
52
54
  files:
@@ -55,8 +57,14 @@ files:
55
57
  - LICENSE
56
58
  - README.md
57
59
  - Rakefile
60
+ - TODO.txt
61
+ - bin/pcm2pwm
62
+ - bin/split_motifs
58
63
  - bioinform.gemspec
59
64
  - lib/bioinform.rb
65
+ - lib/bioinform/cli.rb
66
+ - lib/bioinform/cli/pcm2pwm.rb
67
+ - lib/bioinform/cli/split_motifs.rb
60
68
  - lib/bioinform/data_models.rb
61
69
  - lib/bioinform/data_models/collection.rb
62
70
  - lib/bioinform/data_models/pcm.rb
@@ -72,17 +80,17 @@ files:
72
80
  - lib/bioinform/support/advanced_scan.rb
73
81
  - lib/bioinform/support/array_product.rb
74
82
  - lib/bioinform/support/array_zip.rb
75
- - lib/bioinform/support/callable_symbol.rb
76
83
  - lib/bioinform/support/collect_hash.rb
77
84
  - lib/bioinform/support/deep_dup.rb
78
85
  - lib/bioinform/support/delete_many.rb
79
- - lib/bioinform/support/has_keys.rb
80
86
  - lib/bioinform/support/inverf.rb
81
87
  - lib/bioinform/support/multiline_squish.rb
82
88
  - lib/bioinform/support/partial_sums.rb
83
89
  - lib/bioinform/support/same_by.rb
84
- - lib/bioinform/support/yaml_dump_file.rb
85
90
  - lib/bioinform/version.rb
91
+ - spec/cli/cli_spec.rb
92
+ - spec/cli/pcm2pwm_spec.rb
93
+ - spec/cli/split_motifs_spec.rb
86
94
  - spec/data_models/pcm_spec.rb
87
95
  - spec/data_models/pm_spec.rb
88
96
  - spec/data_models/ppm_spec.rb
@@ -95,10 +103,8 @@ files:
95
103
  - spec/support/advanced_scan_spec.rb
96
104
  - spec/support/array_product_spec.rb
97
105
  - spec/support/array_zip_spec.rb
98
- - spec/support/callable_symbol_spec.rb
99
106
  - spec/support/collect_hash_spec.rb
100
107
  - spec/support/delete_many_spec.rb
101
- - spec/support/has_keys_spec.rb
102
108
  - spec/support/inverf_spec.rb
103
109
  - spec/support/multiline_squish_spec.rb
104
110
  - spec/support/partial_sums_spec.rb
@@ -131,6 +137,9 @@ summary: Classes for work with different input formats of positional matrices an
131
137
  several useful extensions for Enumerable module like parametric map and callable
132
138
  symbols
133
139
  test_files:
140
+ - spec/cli/cli_spec.rb
141
+ - spec/cli/pcm2pwm_spec.rb
142
+ - spec/cli/split_motifs_spec.rb
134
143
  - spec/data_models/pcm_spec.rb
135
144
  - spec/data_models/pm_spec.rb
136
145
  - spec/data_models/ppm_spec.rb
@@ -143,10 +152,8 @@ test_files:
143
152
  - spec/support/advanced_scan_spec.rb
144
153
  - spec/support/array_product_spec.rb
145
154
  - spec/support/array_zip_spec.rb
146
- - spec/support/callable_symbol_spec.rb
147
155
  - spec/support/collect_hash_spec.rb
148
156
  - spec/support/delete_many_spec.rb
149
- - spec/support/has_keys_spec.rb
150
157
  - spec/support/inverf_spec.rb
151
158
  - spec/support/multiline_squish_spec.rb
152
159
  - spec/support/partial_sums_spec.rb
@@ -1,50 +0,0 @@
1
- # Useful extension for &:symbol - syntax to make it possible to pass arguments for method in block
2
- # ['abc','','','def','ghi'].tap(&:delete.('')) # ==> ['abc','def','ghi']
3
- # [1,2,3].map(&:to_s.(2)) # ==> ['1','10','11']
4
- # ['abc','cdef','xy','z','wwww'].select(&:size.() == 4) # ==> ['cdef', 'wwww']
5
- # ['abc','aaA','AaA','z'].count(&:upcase.().succ == 'AAB') # ==> 2
6
- # [%w{1 2 3 4 5},%w{6 7 8 9}].map(&:join.().length) # ==> [5,4]
7
- class Symbol
8
- def call(*args, &block)
9
- obj = BasicObject.new.instance_exec(self,args,block) do |meth,params,block|
10
- @postprocess_meth = [meth]
11
- @postprocess_args = [params]
12
- @postprocess_block = [block]
13
- self
14
- end
15
-
16
- def obj.to_proc
17
- # proc/lambda are methods that cannot be used in BasicObject. It's possible to use ->(slf){...} syntax since ruby-1.9.3 p194 but it's too modern and not widely spreaded yet
18
- ::Proc.new do |slf|
19
- @postprocess_meth.zip(@postprocess_args,@postprocess_block).inject(slf) do |result,(call_meth,call_args,call_block)|
20
- result.send(call_meth, *call_args,&call_block)
21
- end
22
- end
23
- end
24
-
25
- def obj.method_missing(meth,*args,&block)
26
- @postprocess_meth << meth
27
- @postprocess_args << args
28
- @postprocess_block << block
29
- self
30
- end
31
-
32
- def obj.==(other)
33
- method_missing(:==, other)
34
- end
35
-
36
- obj
37
- end
38
- end
39
-
40
-
41
- =begin
42
- # Much simplier but ['abc','cdef','xy','z','wwww'].select(&:size.() == 4) wouldn't work
43
- class Symbol
44
- def call(*args, &block)
45
- proc do |recv|
46
- recv.__send__(self, *args, &block)
47
- end
48
- end
49
- end
50
- =end
@@ -1,14 +0,0 @@
1
- class Hash
2
- def has_all_keys?(*keys)
3
- keys.all?{|key| has_key? key}
4
- end
5
- def has_any_key?(*keys)
6
- keys.any?{|key| has_key? key}
7
- end
8
- def has_none_key?(*keys)
9
- keys.none?{|key| has_key? key}
10
- end
11
- def has_one_key?(*keys)
12
- keys.one?{|key| has_key? key}
13
- end
14
- end
@@ -1,5 +0,0 @@
1
- require 'yaml'
2
-
3
- def YAML.dump_file(obj,filename)
4
- File.open(filename, 'w'){|f| YAML.dump(obj,f)}
5
- end
@@ -1,66 +0,0 @@
1
- require 'spec_helper'
2
- require 'bioinform/support/callable_symbol'
3
-
4
- # TODO: organize and write more correct descriptions
5
- describe Symbol do
6
- describe '#call' do
7
- context 'when symbol curries a block' do
8
- it 'should pass a block to a corresponding proc' do
9
- :map.(&:to_s).to_proc.call([1,2,3]).should == ['1','2','3']
10
- [[1,2,3],[4,5,6]].map(&:map.(&:to_s)).should == [['1','2','3'],['4','5','6']]
11
- [[1,2,3],[4,5,6]].map(&:map.(&:to_s.(2))).should == [['1','10','11'],['100','101','110']]
12
- ['abc','cdef','xy','z','wwww'].select(&:size.() == 4).should == ['cdef', 'wwww']
13
-
14
- [%w{1 2 3 4 5},%w{6 7 8 9 10}].map(&:join.().length).should == [5,6] # method chaining
15
- ['abc','aaA','AaA','z'].count(&:upcase.().succ == 'AAB').should == 2 # method chaining with ==
16
- [[1,2,3]].map( &:map.(&:to_s.(2)).map(&:to_i) ).should == [[1,10,11]] # method chaining with block on initial symbol and on later symbols
17
- end
18
- end
19
-
20
- context 'returned object' do
21
-
22
- it 'should have to_proc method' do
23
- expect { :to_s.() }.to respond_to :to_proc
24
- expect { :to_s.(2) }.to respond_to :to_proc
25
- expect { :to_s.(2) == '110' }.to respond_to :to_proc
26
- expect { :to_s.(2).postprocess('arg1','arg2') }.to respond_to :to_proc
27
- end
28
-
29
- context 'corresponding proc' do
30
- it 'should call method, corresponding to symbol, on first argument' do
31
- stub_obj = double('obj')
32
- stub_obj.should_receive(:to_s).exactly(:twice)
33
- prc_1 = :to_s.(2).to_proc
34
- prc_2 = :to_s.(2).to_proc # When used with &, to_proc can be omitted: it's implicitly casted on call (see other examples)
35
- prc_1.call(stub_obj) # These forms are almost equivalent, but second is much more concise
36
- stub_obj.tap(&prc_2)
37
- end
38
- context 'when multiple arguments of call specified' do
39
- it 'should call using given arguments' do
40
- stub_obj = double('obj')
41
- stub_obj.should_receive(:gsub).with('before','after')
42
- prc = :gsub.('before','after')
43
- stub_obj.tap(&prc)
44
- end
45
- end
46
- context 'when the only argument of call specified' do
47
- it 'should call using given argument' do
48
- stub_obj = double('obj')
49
- stub_obj.should_receive(:to_s).with(2)
50
- prc = :to_s.(2)
51
- stub_obj.tap(&prc)
52
- end
53
- end
54
- context 'when no arguments given' do
55
- it 'should call without any arguments' do
56
- stub_obj = double('obj')
57
- stub_obj.should_receive(:to_s).with()
58
- prc = :to_s.()
59
- stub_obj.tap(&prc)
60
- end
61
- end
62
- end
63
-
64
- end
65
- end
66
- end
@@ -1,48 +0,0 @@
1
- require 'spec_helper'
2
- require 'bioinform/support/has_keys'
3
-
4
- describe Hash do
5
- describe '#has_all_keys?' do
6
- it 'should be true if all given keys are at place' do
7
- {a: 3, b: 6, c: 7, d: 13}.has_all_keys?(:a, :c).should be_true
8
- end
9
-
10
- it 'should be false if any given of keys is missing' do
11
- {a: 3, b: 6, c: 7, d: 13}.has_all_keys?(:a, :x).should be_false
12
- end
13
- end
14
-
15
- describe '#has_any_key?' do
16
- it 'should be true if any of given keys is at place' do
17
- {a: 3, b: 6, c: 7, d: 13}.has_any_key?(:a, :x).should be_true
18
- end
19
-
20
- it 'should be false if no one of given is missing' do
21
- {a: 3, b: 6, c: 7, d: 13}.has_any_key?(:x, :y).should be_false
22
- end
23
- end
24
-
25
- describe '#has_none_key?' do
26
- it 'should be true if all given keys are missing' do
27
- {a: 3, b: 6, c: 7, d: 13}.has_none_key?(:x, :y).should be_true
28
- end
29
-
30
- it 'should be false if any of given keys is at place' do
31
- {a: 3, b: 6, c: 7, d: 13}.has_none_key?(:a, :y).should be_false
32
- end
33
- end
34
-
35
- describe '#has_one_key?' do
36
- it 'should be true if one of given keys is present' do
37
- {a: 3, b: 6, c: 7, d: 13}.has_one_key?(:x, :a).should be_true
38
- end
39
-
40
- it 'should be false if many of given keys are present' do
41
- {a: 3, b: 6, c: 7, d: 13}.has_one_key?(:a, :c).should be_false
42
- end
43
-
44
- it 'should be false if none of given keys is at place' do
45
- {a: 3, b: 6, c: 7, d: 13}.has_one_key?(:x, :y).should be_false
46
- end
47
- end
48
- end