rubyexts 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,2 +1,4 @@
1
1
  = Version 0.0.1
2
2
  * Imported from Rango
3
+ = Version 0.0.2
4
+ * Imported mixins from Rango
@@ -129,9 +129,11 @@ module AttributeMixin
129
129
  # Post.new.updated?
130
130
  # # => true
131
131
  # @since 0.0.2
132
- def questionable(name, default_value)
132
+ # questionable(:testing) { }
133
+ def questionable(name, default_value = nil, &block)
133
134
  define_method("#{name}?") do
134
135
  unless self.instance_variables.include?(name.to_sym)
136
+ default_value = block_given? ? self.instance_eval(&block) : default_value
135
137
  self.instance_variable_set("@#{name}", default_value)
136
138
  end
137
139
  self.instance_variable_get("@#{name}")
@@ -32,9 +32,7 @@ module Kernel
32
32
  require library
33
33
  rescue LoadError => exception
34
34
  message = "Gem #{gemname} isn't installed. Run sudo gem install #{gemname}. (#{exception.inspect})"
35
- logger = Rango.logger.method(options[:level] || :error)
36
- callable = defined?(Rango.logger) ? logger : method(:puts)
37
- callable.call(message)
35
+ puts message
38
36
  raise exception
39
37
  end
40
38
 
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+
3
+ # TODO: documentation
4
+ # TODO: specs
5
+ require "logger"
6
+ require "rubyexts/string" # String#colorize
7
+
8
+ module RubyExts
9
+ class Logger < ::Logger
10
+ # @since 0.0.1
11
+ def initialize(output = STDERR)
12
+ super(output)
13
+ self.setup
14
+ end
15
+
16
+ # @since 0.0.1
17
+ def setup
18
+ self.level = ::Logger::DEBUG
19
+ self.datetime_format = "%H:%M:%S"
20
+ self.setup_format
21
+ end
22
+
23
+ # @since 0.0.1
24
+ def exception(exception)
25
+ self.error("#{exception.message} (#{exception.class})")
26
+ exception.backtrace.each do |line|
27
+ unless line.match(/thin|eventmachine/)
28
+ STDERR.puts("- #{line.colorize.cyan}")
29
+ end
30
+ end
31
+ end
32
+
33
+ # Logger methods can takes more arguments and they returns array with arguments
34
+ # NOTE: why we dup args each time? Because we colorize messages, but if logger method
35
+ # is used for handling requests, we just need to send noncolored messages as response.
36
+ # @since 0.0.1
37
+ def debug(*args)
38
+ original = args.dup
39
+ args.map { |arg| super(arg) }
40
+ return original
41
+ end
42
+
43
+ # @since 0.0.1
44
+ def info(*args)
45
+ original = args.dup
46
+ args.map { |arg| super(arg) }
47
+ return original
48
+ end
49
+
50
+ # @since 0.0.1
51
+ def warn(*args)
52
+ original = args.dup
53
+ args.map { |arg| super(arg) }
54
+ return original
55
+ end
56
+
57
+ # @since 0.0.1
58
+ def error(*args)
59
+ original = args.dup
60
+ args.map { |arg| super(arg) }
61
+ return original
62
+ end
63
+
64
+ # @since 0.0.1
65
+ def fatal(*args)
66
+ original = args.dup
67
+ args.map { |arg| super(arg) }
68
+ return original
69
+ end
70
+
71
+ # Project.logger.inspect(@posts, item)
72
+ # Project.logger.inspect("@post" => @post)
73
+ # @since 0.0.1
74
+ def inspect(*args)
75
+ if args.first.is_a?(Hash) && args.length.eql?(1)
76
+ args.first.each do |name, value|
77
+ self.debug("#{name}: #{value.inspect}")
78
+ end
79
+ else
80
+ args = args.map { |arg| arg.inspect }
81
+ self.debug(*args)
82
+ end
83
+ end
84
+
85
+ # @since 0.0.1
86
+ def setup_format
87
+ self.formatter = lambda do |severity, datetime, progname, msg|
88
+ # logger.debug(object_to_inspect)
89
+ msg = msg.inspect unless msg.is_a?(String)
90
+ datetime = datetime.strftime("[%H:%M:%S]")
91
+ case severity
92
+ when "DEBUG" then "#{datetime} #{msg.colorize.yellow}\n"
93
+ when "INFO" then "#{datetime} #{msg.colorize.green}\n"
94
+ when "WARN" then "#{datetime} #{msg.colorize.yellow}\n"
95
+ when "ERROR" then "#{datetime} #{msg.colorize.red}\n"
96
+ when "FATAL" then "#{datetime} #{msg.colorize.red.bold}\n"
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+
3
+ # from merb-core
4
+ module RubyExts
5
+ module Chainable
6
+ # Allows the definition of methods on a class that will be available via
7
+ # super.
8
+ #
9
+ # ==== Examples
10
+ # class Foo
11
+ # extend RubyExts::Chainable
12
+ # chainable do
13
+ # def hello
14
+ # "hello"
15
+ # end
16
+ # end
17
+ # end
18
+ #
19
+ # class Foo
20
+ # def hello
21
+ # super + " Merb!"
22
+ # end
23
+ # end
24
+ #
25
+ # # Example with mixin:
26
+ # module TestMixin
27
+ # extend RubyExts::Chainable
28
+ # chainable do
29
+ # def test
30
+ # "from mixin!"
31
+ # end
32
+ # end
33
+ # end
34
+ #
35
+ # class Test
36
+ # include TestMixin
37
+ # def test
38
+ # "hello " + super
39
+ # end
40
+ # end
41
+ #
42
+ # puts Test.new.test
43
+ #
44
+ #
45
+ # Foo.new.hello #=> "hello Merb!"
46
+ #
47
+ # ==== Parameters
48
+ # &block::
49
+ # a block containing method definitions that should be
50
+ # marked as chainable
51
+ #
52
+ # ==== Returns
53
+ # Module:: The anonymous module that was created
54
+ def chainable(method = nil, &block)
55
+ if method.nil? && block_given?
56
+ mixin = Module.new(&block)
57
+ include mixin
58
+ return mixin
59
+ elsif method && ! block_given?
60
+ # TODO
61
+ # def test
62
+ # # ...
63
+ # end
64
+ # chainable :test
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ # class Test
4
+ # extend Rango::Hookable
5
+ # install_hook do |instance|
6
+ # p instance
7
+ # end
8
+ #
9
+ # def initialize
10
+ # p self
11
+ # end
12
+ # end
13
+ #
14
+ # Test.new
15
+
16
+ module RubyExts
17
+ module Hookable
18
+ def new(*args)
19
+ instance = super(*args)
20
+ self.hooks.each { |hook| hook.call(instance) }
21
+ return instance
22
+ end
23
+
24
+ def hooks
25
+ @hooks ||= Array.new
26
+ end
27
+
28
+ def install_hook(&block)
29
+ self.hooks.push(block)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,89 @@
1
+ # encoding: utf-8
2
+
3
+ # boot: after rango.rb
4
+
5
+ module RubyExts
6
+ # This mixin will be included also to project or your custom app main namespace
7
+ module ImportMixin
8
+ # class Project
9
+ # extend Rango::ImportMixin
10
+ # end
11
+ def self.extended(base)
12
+ unless base.respond_to?(:root)
13
+ class << base
14
+ def root
15
+ File.dirname(caller[1].split(":").first)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ # class Project
22
+ # class << self
23
+ # extend Rango::ImportMixin
24
+ # end
25
+ # end
26
+ def self.included(base)
27
+ unless base.respond_to?(:root)
28
+ base.class_eval do
29
+ def root
30
+ File.dirname(caller.last.split(":").first)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ # @since 0.0.1
37
+ # @example
38
+ # Project.import("blog/views")
39
+ # Project.import("blog/views", soft: true)
40
+ # @param [String] path Path to file which will be loaded using +Kernel#load+ if +Project.settings.debug+ is true or +Kernel#require+ if not.
41
+ # @param [Hash[soft: Boolean(default true)], @optional] options
42
+ # @raise [LoadError] Unless <tt>soft: true</tt> option is used, it will raise +LoadError+ if the file wasn't found.
43
+ # @return [Boolean] If loading suceed.
44
+ def import(path, options = Hash.new)
45
+ # it is better than rescue LoadError, because
46
+ # LoadError can be raise inside the required file
47
+ fullpath = self.find_absolute(path)
48
+ if fullpath.nil? && options[:soft] # any file found and soft importing enabled
49
+ # do nothing
50
+ elsif fullpath.nil? && !options[:soft] # any file found and soft importing disabled
51
+ raise LoadError, "File #{path.inspect} (treated as #{fullpath.inspect}) doesn't exist"
52
+ elsif !fullpath.nil? # the file was found
53
+ Kernel.load(fullpath)
54
+ elsif !fullpath.nil? # the file was found
55
+ Kernel.require(fullpath)
56
+ end
57
+ end
58
+
59
+ # @since 0.0.2
60
+ def import_first(paths, options = Hash.new)
61
+ paths.each do |path|
62
+ fullpath = self.find_absolute(path)
63
+ next if fullpath.nil?
64
+ return self.import(fullpath, options)
65
+ end
66
+ raise LoadError unless options[:soft]
67
+ end
68
+
69
+ # @since 0.0.1
70
+ # @param [String] path Path to loaded file.
71
+ # @return [Boolean] If the loading was successful.
72
+ def import!(path)
73
+ path = File.join(self.root, path)
74
+ file = self.find_absolute(path)
75
+ Kernel.load(file)
76
+ end
77
+
78
+ def find(file)
79
+ ["#{file}.rb", file].find do |file|
80
+ File.exist?(file)
81
+ end
82
+ end
83
+
84
+ def find_absolute(file)
85
+ file = File.join(self.root, file) unless file.match(%r[^/])
86
+ self.find(file)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ # Include this module to strategy superclass
4
+ module RubyExts
5
+ module StrategyMixin
6
+ class << self
7
+ attribute :strategies, Array.new
8
+
9
+ def register
10
+ self.strategies.push(self)
11
+ end
12
+
13
+ def find(*args)
14
+ self.strategies.find { |strategy| strategy.match?(*args) }
15
+ end
16
+ end
17
+
18
+ def match?(*args)
19
+ raise "This method must be redefined in subclasses"
20
+ end
21
+
22
+ def run(*args)
23
+ raise "This method must be redefined in subclasses"
24
+ end
25
+
26
+ # define setup method if you need it
27
+ end
28
+ end
@@ -1,26 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  class Object
4
- # *Unlike* that method however, a +NoMethodError+ exception will *not* be raised
5
- # and +nil+ will be returned instead, if the receiving object is a +nil+ object or NilClass.
6
- #
7
- # Invokes the method identified by the symbol +method+, passing it any arguments
8
- # and/or the block specified, just like the regular Ruby <tt>Object#send</tt> does.
9
- #
10
- # @author Botanicus
11
- # @since 0.0.3
12
- # @return [Object, nil] Return value of object.send(method) if object respond to method or nil
13
- # @param [Symbol] Method which will be called on object if object respond to this method
14
- # @param [Object, optional] Arguments for +method+ argument
15
- # @yield [block, optional] Block for +method+ argument
16
- # @example
17
- # @post.try(:name) # instead @post && @post.name
18
- # eBook.try(:find, 1)
19
- # @post.try(:collect) { |p| p.name }
20
- def try(method, *args, &block)
21
- self.send(method, *args, &block) if self.respond_to?(method)
22
- end
23
-
24
4
  # The opposite of <tt>#nil?</tt>.
25
5
  #
26
6
  # @author Botanicus
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ class Object
4
+ # *Unlike* that method however, a +NoMethodError+ exception will *not* be raised
5
+ # and +nil+ will be returned instead, if the receiving object is a +nil+ object or NilClass.
6
+ #
7
+ # Invokes the method identified by the symbol +method+, passing it any arguments
8
+ # and/or the block specified, just like the regular Ruby <tt>Object#send</tt> does.
9
+ #
10
+ # @author Botanicus
11
+ # @since 0.0.3
12
+ # @return [Object, nil] Return value of object.send(method) if object respond to method or nil
13
+ # @param [Symbol] Method which will be called on object if object respond to this method
14
+ # @param [Object, optional] Arguments for +method+ argument
15
+ # @yield [block, optional] Block for +method+ argument
16
+ # @example
17
+ # @post.try(:name) # instead @post && @post.name
18
+ # eBook.try(:find, 1)
19
+ # @post.try(:collect) { |p| p.name }
20
+ def try(method, *args, &block)
21
+ self.send(method, *args, &block) if self.respond_to?(method)
22
+ end
23
+ end
data/lib/rubyexts.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module RubyExts
4
- VERSION ||= "0.0.1"
4
+ VERSION ||= "0.0.2"
5
5
  end
6
6
 
7
7
  module Kernel
Binary file
data/script/spec CHANGED
@@ -9,4 +9,6 @@ Dir[File.join(File.dirname(__FILE__), "..", "vendor", "*")].each do |path|
9
9
  end
10
10
  end
11
11
 
12
+ ARGV.push("spec") if ARGV.empty?
13
+
12
14
  load File.expand_path(File.join(File.dirname(__FILE__), "..", "vendor", "rspec", "bin", "spec"))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyexts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Jakub \xC5\xA0\xC5\xA5astn\xC3\xBD aka Botanicus"
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
- date: 2009-11-23 00:00:00 +00:00
11
+ date: 2009-12-03 00:00:00 +00:00
12
12
  default_executable:
13
13
  dependencies: []
14
14
 
@@ -31,6 +31,11 @@ files:
31
31
  - lib/rubyexts/file.rb
32
32
  - lib/rubyexts/hash.rb
33
33
  - lib/rubyexts/kernel.rb
34
+ - lib/rubyexts/logger.rb
35
+ - lib/rubyexts/mixins/chainable.rb
36
+ - lib/rubyexts/mixins/hookable.rb
37
+ - lib/rubyexts/mixins/import.rb
38
+ - lib/rubyexts/mixins/strategy.rb
34
39
  - lib/rubyexts/module.rb
35
40
  - lib/rubyexts/object.rb
36
41
  - lib/rubyexts/object_space.rb
@@ -40,6 +45,7 @@ files:
40
45
  - lib/rubyexts/string.rb
41
46
  - lib/rubyexts/time.rb
42
47
  - lib/rubyexts/time_dsl.rb
48
+ - lib/rubyexts/try.rb
43
49
  - lib/rubyexts/try_dup.rb
44
50
  - lib/rubyexts/unique_array.rb
45
51
  - lib/rubyexts.rb