TbpgrUtils

TbpgrUtils is Utilities.

Installation

Add this line to your application's Gemfile:

gem 'tbpgr_utils'

And then execute:

$ bundle

Or install it yourself as:

$ gem install tbpgr_utils

Usage

List

class/module/method mean
TbpgrUtils Array#together loop all arrays by block
TbpgrUtils Array#together_map together version of Enumerable#map. together_map has aliases [:tmap, :together_collect, :tcollect]
TbpgrUtils Array#together_reduce together version of Enumerable#reduce. together_reduce has aliases [:treduce, :together_inject, :tinject]
TbpgrUtils Array#together_select together version of Enumerable#select. together_select has aliases [:tselect, :together_find_all, :tfindall]
TbpgrUtils Array#together_with_index loop all arrays by block with index
AttributesInitializable::ClassMethods.attr_accessor_init generate attr_accessor + initializer
AttributesInitializable::ClassMethods.attr_reader_init generate attr_reader + initializer
AttributesInitializable::ClassMethods.attr_writer init generate attr_writer + initializer
Ghostable module help to create ghost method(dynamic method define by ussing method_missing + pattern-method-name)
TbpgrUtils Kernel#bulk_define_methods define methods to classes. methods have simple return value.
TestToolbox Kernel#capture_stdout capture STDOUT
TestToolbox Kernel#dp_line debug print line for print-debugging
TbpgrUtils Kernel#print_eval Print code + eval result
TbpgrUtils Kernel#puts_eval Puts code + eval result
TbpgrUtils Kernel#bulk_puts_eval Puts each-line-code + eval result
TbpgrUtils Module.alias_methods create alias methods
TbpgrUtils Object#any_of? if self match any one of items, return true
TbpgrUtils Object#boolean? data type check for boolean
TbpgrUtils Object#my_methods return public/protected/private self define methods
TbpgrUtils Object#to_bool syntax sugar of !!. convert [false, nil] => fasel, other => true.
TbpgrUtils String#justify_table justify pipe format table string
Templatable module get result from template + placeholder
TemplateMethodable module for Template Method Pattern

Array#together

require 'tbpgr_utils'

alpha = %w{one two three}
numbers = %w{1 2 3}
[alpha, numbers].together do |first, second|
  print "#{first}:#{second}\n"  # => output one:1, two:2, three:3
end

Array#together_map(or tmap, together_collect, tcollect)

require 'tbpgr_utils'

alpha = %w{one two three}
numbers = %w{1 2 3}
ret = [alpha, numbers].together_map {|first, second|"#{first}:#{second}"}
print ret # => output [one:1, two:2, three:3]

if you want to return multi array, following.

require 'tbpgr_utils'

alpha = %w{one two three}
numbers = %w{1 2 3}
ret = [alpha, numbers].together_map {|first, second|[["#{first}:ret"], ["#{second}:ret"]]}
print ret # => output [["one:ret", "two:ret", "three:ret"],["1:ret", "2:ret", "3:ret"]]

Array#together_reduce(or :treduce, :together_inject, :tinject)

  • if you want to single return
firsts = [1, 2, 3, 4]
seconds =  [4, 2, 3, 1]
ret = [firsts, seconds].together_reduce{|memo, first, second|memo + first + second}
print ret # => output  20
  • if you want to single return with init value
firsts = [1, 2, 3, 4]
seconds =  [4, 2, 3, 1]
ret = [firsts, seconds].together_reduce(10){|memo, first, second|memo + first + second}
print ret # => output  30
  • if you want to single return with init string value
firsts = %w{a b c}
seconds =  %w{1 2 3}
ret = [firsts, seconds].together_reduce('start-'){|memo, first, second|memo + first + second}
print ret # => output 'start-a1b2c3'
  • if you want to single return with init Array value
firsts = [1, 2, 3, 4]
seconds =  [4, 2, 3, 1]
ret = [firsts, seconds].together_reduce([]){|memo, first, second|memo << first + second}
print ret # => output [5, 4, 6, 5]
  • if you want to single return with init Hash value
firsts = [1, 2, 3, 4]
seconds =  [4, 2, 3, 1]
ret = [firsts, seconds].together_reduce({}){|memo, first, second|memo[first] = second;memo}
print ret # => output {1=>4, 2=>2, 3=>3, 4=>1}

Array#together_select(or tselect, together_find_all, tfindall)

require 'tbpgr_utils'

firsts = [1, 2, 3, 4]
seconds =  [4, 2, 3, 1]
ret = [firsts, seconds].together_select{|first, second|first == second}
print ret # => output  [[2, 3], [2, 3]]

if you want to return multi array, following.

require 'tbpgr_utils'

firsts = [1, 2, 3, 4]
seconds =  [4, 2, 3, 1]
ret = [firsts, seconds].together_select{|first, second|[first.odd?, second.even?]}
print ret # => output  [[1, 3], [4, 2]]

Array#together_with_index

require 'tbpgr_utils'

alpha = %w{one two three}
numbers = %w{1 2 3}
[alpha, numbers].together_with_index do |first, second, index|
  print "#{index.to_s}:#{first}:#{second}\n"  # => output 0:one:1, 1:two:2, 2:three:3
end

AttributesInitializable::ClassMethods.attr_accessor_init

require 'attributes_initializable'

class AccessorSample
  include AttributesInitializable
  attr_accessor_init :atr1, :atr2
end

atr_sample1 = AccessorSample.new :atr1 => 'atr1', :atr2 => 'atr2'
p atr_sample1.atr1 # => atr1
p atr_sample1.atr2 # => atr2

atr_sample2 = AccessorSample.new do |a|
  a.atr1 = 'atr1'
  a.atr2 = 'atr2'
end
p atr_sample2.atr1 # => atr1
p atr_sample2.atr2 # => atr2

same mean code is

class AccessorSample
  attr_accessor :atr1, :atr2

  def initialize(values = nil, &block)
    return yield self if block
    @atr1 = values[:atr1]
    @atr2 = values[:atr2]
  end
end

atr_sample1 = AccessorSample.new :atr1 => 'atr1', :atr2 => 'atr2'
p atr_sample1.atr1 # => atr1
p atr_sample1.atr2 # => atr2

atr_sample2 = AccessorSample.new do |a|
  a.atr1 = 'atr1'
  a.atr2 = 'atr2'
end
p atr_sample2.atr1 # => atr1
p atr_sample2.atr2 # => atr2

AttributesInitializable::ClassMethods.attr_reader_init

require 'attributes_initializable'

class AccessorSample
  include AttributesInitializable
  attr_reader_init :atr1, :atr2
end

atr_sample1 = AccessorSample.new :atr1 => 'atr1', :atr2 => 'atr2'
p atr_sample1.atr1 # => atr1
p atr_sample1.atr2 # => atr2

# can not use writer.
# atr_sample2 = AccessorSample.new do |a|
#   a.atr1 = 'atr1'
#   a.atr2 = 'atr2'
# end

same mean code is

class AccessorSample
  attr_reader :atr1, :atr2

  def initialize(values = nil, &block)
    return yield self if block
    @atr1 = values[:atr1]
    @atr2 = values[:atr2]
  end
end

atr_sample1 = AccessorSample.new :atr1 => 'atr1', :atr2 => 'atr2'
p atr_sample1.atr1 # => atr1
p atr_sample1.atr2 # => atr2

# can not use writer.
# atr_sample2 = AccessorSample.new do |a|
#   a.atr1 = 'atr1'
#   a.atr2 = 'atr2'
# end

AttributesInitializable::ClassMethods.attr_writer_init

require 'attributes_initializable'

class AccessorSample
  include AttributesInitializable
  attr_writer_init :atr1, :atr2
end

atr_sample1 = AccessorSample.new :atr1 => 'atr1', :atr2 => 'atr2'
# can not use reader
# p atr_sample1.atr1 # => atr1
# p atr_sample1.atr2 # => atr2
atr_sample1.instance_variable_get "@atr1" # => atr1
atr_sample1.instance_variable_get "@atr2" # => atr2

atr_sample2 = AccessorSample.new do |a|
  a.atr1 = 'atr1'
  a.atr2 = 'atr2'
end

# can not use reader
# p atr_sample2.atr1 # => atr1
# p atr_sample2.atr2 # => atr2
atr_sample2.instance_variable_get "@atr1" # => atr1
atr_sample2.instance_variable_get "@atr2" # => atr2

same mean code is

class AccessorSample
  attr_writer :atr1, :atr2

  def initialize(values = nil, &block)
    return yield self if block
    @atr1 = values[:atr1]
    @atr2 = values[:atr2]
  end
end

atr_sample1 = AccessorSample.new :atr1 => 'atr1', :atr2 => 'atr2'
# can not use reader
# p atr_sample1.atr1 # => atr1
# p atr_sample1.atr2 # => atr2
atr_sample1.instance_variable_get "@atr1" # => atr1
atr_sample1.instance_variable_get "@atr2" # => atr2

atr_sample2 = AccessorSample.new do |a|
  a.atr1 = 'atr1'
  a.atr2 = 'atr2'
end
# can not use reader
# p atr_sample2.atr1 # => atr1
# p atr_sample2.atr2 # => atr2
atr_sample2.instance_variable_get "@atr1" # => atr1
atr_sample2.instance_variable_get "@atr2" # => atr2

Ghostable

  • include Ghostable
  • create ghost method by using Ghostable::ghost_method
  • ghost_method first_args = method_name_pattern
  • ghost_method second_args = method_base_name Symbol(using in Ghostable internal logic)
  • ghost_method third = block. this block is main logic. block can use args[method_name, *args, &block]

sample ghost method define module.

require 'ghostable'
module Checkable
  include Ghostable
  ghost_method /check_range_.*\?$/, :check_range do |method_name, *args, &block|
    method_name.to_s =~ /(check_range_)(\d+)(_to_)(\d*)/
    from = $2.to_i
    to = $4.to_i
    value = args.first
    (from..to).include? value
  end

  ghost_method /^contain_.*\?$/, :check_contain do |method_name, *args, &block|
    method_name.to_s =~ /^(contain_)(.*)(\?)/
    word = $2
    value = args.first
    value.include? word
  end
end
  • use ghost method

sample ghost method use class

class SampleChecker
  include Checkable
end

sample = SampleChecker.new
sample.check_range_3_to_5?(4) # => return true
sample.check_range_3_to_5?(6) # => return false
sample.check_range_3_to_6?(6) # => return true

sample.contain_hoge? "test_hoge_test" # => return true
sample.contain_hoge? "test_hige_test" # => return false
sample.contain_hige? "test_hige_test" # => return true

Kernel#capture_stdout

capture STDOUT to String. This method can use in STDOUT contents test.

require 'test_toolbox'

result = capture_stdout {puts "test"} # => "test"

# no stdout case. return empty.
result = capture_stdout {sleep 0.1} # => ""(empty)

Kernel#dp_line

debug print line for print-debugging.

require 'test_toolbox'

# default usage
dp_line __LINE__
# output is following. yy = line no.
# => --------------------|filename=|line=yy|--------------------\n

# output with filename
dp_line __LINE__, filename: __FILE__
# output is following. xx=filenamem, yy = line no.
# => --------------------|filename=xx|line=yy|--------------------\n

# output with specific line charactor.
dp_line __LINE__, filename: __FILE__, char: '@'
# output is following. xx=filenamem, yy = line no.
# => @@@@@@@@@@@@@@@@@@@@|filename=xx|line=yy$|@@@@@@@@@@@@@@@@@@@@\n

Kernel#bulk_define_methods

Define methods to classes. Methods have simple return value.

require 'tbpgr_utils'
bulk_define_methods [NilClass, FalseClass], :blank?, true
bulk_define_methods [TrueClass, Numeric], "blank?", false

puts nil.blank?   # => true
puts false.blank? # => true
puts true.blank?  # => false
puts 1.blank?     # => false

bulk_define_methods [NilClass, FalseClass], [:blank?, :present?], [true, false]
bulk_define_methods [TrueClass, Numeric], [:blank?, :present?], [false, true]

puts nil.blank?     # => true
puts nil.present?   # => false
puts false.blank?   # => true
puts false.present? # => false
puts true.blank?    # => false
puts true.present?  # => true
puts 1.blank?       # => false
puts 1.present?     # => true

if you don't use bulk_define_methods, followinng code is same mean.

class NilClass
 def blank?
   true
 end

 def present?
   false
 end
end

class FalseClass
 def blank?
   true
 end

 def present?
   false
 end
end

Kernel#print_eval

This method for sample code. for manual, for blog-entry's-snippet ...etc.

print_eval 8/4, binding  # => 8/4 # => 2

message = 'msg'
print_eval "hoge-#{message}", binding # => "hoge-#{message}" # => "hoge-msg"

output

8/4 # => 2"hoge-#{message}" # => "hoge-msg"

Kernel#puts_eval

This method for sample code. for manual, for blog-entry's-snippet ...etc.

puts_eval 8/4, binding

message = 'msg'
puts_eval "hoge-#{message}", binding # => "hoge-#{message}" # => "hoge-msg"

output

8/4 # => 2
"hoge-#{message}" # => "hoge-msg"

Kernel#bulk_puts_eval

multi line version of puts_eval.

message = "msg"
bulk_puts_eval binding, <<-EOS
"hoge-hige1" + "add" + message
"hoge-hige2" + "add" + message
EOS

output

"hoge-hige1" + "add" + message # => "hoge-hige1addmsg"
"hoge-hige2" + "add" + message # => "hoge-hige2addmsg"

Module.alias_methods

create alias methods.

require "tbpgr_utils"

class Hoge
  def hoge
    "hoge"
  end

  alias_methods [:hige, :hege, :huge], :hoge
end

Hoge.new.hoge # => "hoge"
Hoge.new.hige # => "hoge"
Hoge.new.hege # => "hoge"
Hoge.new.huge # => "hoge"

same code is...

class Hoge
  def hoge
    "hoge"
  end

  alias_method :hige, :hoge
  alias_method :hege, :hoge
  alias_method :huge, :hoge
end

Object#any_of?

require 'tbpgr_utils'

p 'hoge'.any_of? 'hoge', 'hige'    # =>true
p 'hoge'.any_of?(*%w{hoge hige})    # =>true
p 'hige'.any_of? 'hoge', 'hige'    # =>true
p 'hege'.any_of? 'hoge', 'hige'    # =>false
p 1.any_of? 1, 2, 3                # =>true
p 4.any_of? 1, 2, 3                # =>false

Object#boolean?

require 'tbpgr_utils'

p true.boolean?    # =>true
p false.boolean?   # =>true
p nil.boolean?     # =>false
p "".boolean?      # =>false
p "true".boolean?  # =>false

Object#my_methods

require 'tbpgr_utils'

class Hoge
  def hgoe
  end

  protected
  def hige
  end

  private
  def hege
  end
end

p Hoge.new.my_methods # =>[:hoge, :hige, :hege]

Object#to_bool

require 'tbpgr_utils'

p true.to_bool # => true
p false.to_bool # => false
p 'true'.to_bool # => true
p 'false'.to_bool # => true
p nil.to_bool # => false
p 0.to_bool # => true

String#justify_table

require 'tbpgr_utils'

str =<<-EOS
|* hogehogehoge|* hege|* hige|
|test|tester|testest|
|test|tester|aaaaaaaaaaaaaaaaaaaaaaatestest|
EOS

puts str.justify_table

output

|* hogehogehoge|* hage|* hige                        |
|test          |tester|testest                       |
|test          |tester|aaaaaaaaaaaaaaaaaaaaaaatestest|

Templatable

  • include Templatable
  • set template by here-document
  • in template, parameter must name 'placeholders[:xxxxx]'. xxxxx is your favorite name.
  • when create instance, you must set materials to create template. after, you can get this value from @materials.
  • you must create manufactured_xxx methods. xxx is each-placeholder name.
  • you can get result by 'result' method.
require 'templatable'

class TemplateUser
  include Templatable
  template <<-EOS
line1:<%=placeholders[:hoge]%>
line2:<%=placeholders[:hige]%>
  EOS

  def manufactured_hoge
    "hoge-#{@materials}"
  end

  def manufactured_hige
    "hige-#{@materials}"
  end
end

p TemplateUser.new('sample').result

output

line1:hoge-sample
line2:hige-sample

TemplateMethodable

sample usage

require "template_methodable"
# sample BaseClass
class BaseDeveloper
  include TemplateMethodable
  must_impl :easy_coding, :difficult_coding, :normal_coding
  module DIFFICILTY
    EASY = 1
    NORMAL = 2
    DIFFICILT = 3
  end
  def coding(difficulty)
    ret = []
    ret << "start coding"
    case difficulty
    when DIFFICILTY::EASY
      ret << easy_coding
    when DIFFICILTY::NORMAL
      ret << normal_coding
    when DIFFICILTY::DIFFICILT
      ret << difficult_coding
    else
      fail 'error'
    end
    ret << "finish coding"
    ret.join("\n")
  end
end

# sample valid Concrete Class.
class StarDeveloper < BaseDeveloper
  def easy_coding
    "complete 1 minutes"
  end
  def normal_coding
    "complete 10 minutes"
  end
  def difficult_coding
    "complete 59 minutes"
  end
end

# sample invalid Concrete Class. if call NormalDeveloper#difficult_coding, it raises NotImplementedError.
class NormalDeveloper < BaseDeveloper
  def easy_coding
    "complete 10 minutes"
  end
  def normal_coding
    "complete 100 minutes"
  end
end

Relation

if you are Sublime Text2 user, you can use snippet for TbpgrUtils.

https://github.com/tbpgr/tbpgr_utils_snippets

History

  • version 0.0.17 : add Array#together_reduce(or :treduce, :together_inject, :tinject)
  • version 0.0.16 : add Array#together_select(or tselect, together_find_all, tfindall)
  • version 0.0.15 : add Module.alias_methods
  • version 0.0.14 : add Array#together_map(aliases => [tmap, together_collect, tcollect])
  • version 0.0.13 : add Array#together_with_index, Kernel#bulk_puts_eval
  • version 0.0.12 : AttributesInitializable::ClassMethods.attr_reader_init,attr_writer_init
  • version 0.0.11 : add Object#to_bool.
  • version 0.0.10 : add TemplateMethodable module.
  • version 0.0.9 : add TestToolbox module. add Kernel#capture_stdout, Kernel#dp_line
  • version 0.0.8 : add Kernel#bulk_define_methods
  • version 0.0.7 : add Kernel#print_eval, Kernel#puts_eval
  • version 0.0.6 : add Ghostable
  • version 0.0.5 : add Templatable
  • version 0.0.4 : AttributesInitializable::ClassMethods.attr_accessor_init
  • version 0.0.3 : add Object#any_of?
  • version 0.0.2 : loop all arrays by block.
  • version 0.0.1 : first release.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request