From 870c7108c86c951b6c9d94fbfc5653c46e39e48b Mon Sep 17 00:00:00 2001 From: Fred Wu Date: Wed, 12 Sep 2012 02:30:45 +1000 Subject: [PATCH] Initial commit --- .gitignore | 17 +++++ Gemfile | 3 + README.md | 29 ++++++++ Rakefile | 12 ++++ lib/ruby_decorator.rb | 9 +++ lib/ruby_decorators.rb | 49 +++++++++++++ lib/ruby_decorators/.DS_Store | Bin 0 -> 6148 bytes lib/ruby_decorators/stack.rb | 7 ++ lib/ruby_decorators/version.rb | 3 + ruby_decorators.gemspec | 23 ++++++ spec/ruby_decorators_spec.rb | 123 +++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 5 ++ 12 files changed, 280 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 README.md create mode 100644 Rakefile create mode 100644 lib/ruby_decorator.rb create mode 100644 lib/ruby_decorators.rb create mode 100644 lib/ruby_decorators/.DS_Store create mode 100644 lib/ruby_decorators/stack.rb create mode 100644 lib/ruby_decorators/version.rb create mode 100644 ruby_decorators.gemspec create mode 100644 spec/ruby_decorators_spec.rb create mode 100644 spec/spec_helper.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d87d4be --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +*.gem +*.rbc +.bundle +.config +.yardoc +Gemfile.lock +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/README.md b/README.md new file mode 100644 index 0000000..909b934 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Ruby Decorators + +#### Ruby method decorators inspired by Python. + +## Installation + +Add this line to your application's Gemfile: + + gem 'ruby_decorators' + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install ruby_decorators + +## Usage + +```ruby + # TODO +``` + +## License + +Copyright (c) 2012 [Fred Wu](http://fredwu.me/) + +Licensed under the [MIT license](http://fredwu.mit-license.org/). diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..671895e --- /dev/null +++ b/Rakefile @@ -0,0 +1,12 @@ +require "bundler/gem_tasks" + +require 'rake/testtask' + + +Rake::TestTask.new do |t| + t.libs.push 'lib' + t.test_files = FileList['spec/**/*_spec.rb'] + t.verbose = true +end + +task :default => :test diff --git a/lib/ruby_decorator.rb b/lib/ruby_decorator.rb new file mode 100644 index 0000000..833b061 --- /dev/null +++ b/lib/ruby_decorator.rb @@ -0,0 +1,9 @@ +class RubyDecorator + def self.+@ + RubyDecorators::Stack.decorators << self + end + + def +@ + RubyDecorators::Stack.decorators << self + end +end diff --git a/lib/ruby_decorators.rb b/lib/ruby_decorators.rb new file mode 100644 index 0000000..c73e18b --- /dev/null +++ b/lib/ruby_decorators.rb @@ -0,0 +1,49 @@ +require "ruby_decorators/version" +require "ruby_decorator" +require "ruby_decorators/stack" + +module RubyDecorators + def method_added(method_name) + @decorated_methods ||= [] + + return if RubyDecorators::Stack.decorators.empty? || + method_name.to_s =~ /__undecorated_/ || + @decorated_methods.include?(method_name) + + current_decorator = RubyDecorators::Stack.decorators.pop + method_visibility = detect_method_visibility(method_name) + + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + alias_method :__undecorated_#{method_name}, :#{method_name} + + @__decorators ||= {} + @__decorators["#{method_name}"] = current_decorator + + #{method_visibility} + def #{method_name}(*args, &blk) + decorator = #{current_decorator}.new + decorator ||= self.class.instance_variable_get(:@__decorators)["#{method_name}"] + + if args.any? + decorator.call(self.send :__undecorated_#{method_name}, *args, &blk) + else + decorator.call(self.send :__undecorated_#{method_name}, &blk) + end + end + RUBY_EVAL + + @decorated_methods << method_name + end + + private + + def detect_method_visibility(method_name) + if private_method_defined?(method_name) + :private + elsif protected_method_defined?(method_name) + :protected + else + :public + end + end +end diff --git a/lib/ruby_decorators/.DS_Store b/lib/ruby_decorators/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0