-
Notifications
You must be signed in to change notification settings - Fork 1
small but useful annotation library for Ruby
License
kwatch/annotation
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
= README release:: $Release$ copyright:: $Copyright: copyright(c) 2010 kuwata-lab.com all rights reserved $ license:: $License: MIT License $ == About 'annotation.rb' is a very small but pretty good library to introduce Java's annotation or Python's function decorator into Ruby. Using 'annotatin.rb', you can write your code more declarative, like: class MyController < Controller GET('/') def index; ...; end GET('/:id') def show(id); ...; end PUT('/:id') login_required def update(id); ...; end end == Install Install rubygems at first and: $ gem install annotation == Examples ex1. my_controller.rb: require 'annotation' module ControllerAnnotation extend Annotation def GET(imethod, path) (@__routes ||= []) << [path, :GET, imethod] end def POST(imethod, path) (@__routes ||= []) << [path, :POST, imethod] end def login_required(imethod) alias_method "__orig_#{imethod}", imethod s = "def #{imethod}(*args) raise '302 Found' unless @current_user __orig_#{imethod}(*args) end" self.class_eval s # not 'eval(s)' end annotation :GET, :POST, :login_required # !!!!!! end class Controller extend ControllerAnnotation end class MyController < Controller GET('/') def index "index() called." end GET('/:id') def show(id) "show(#{id}) called." end POST('/:id') login_required def update(id) "update(#{id}) called." end p @__routes #=> [["/", :GET, :index], # ["/:id", :GET, :show], # ["/:id", :POST, :update]] end p MyController.new.update(123) #=> 302 Found (RuntimeError) ex2. memoize.rb require 'annotation' module Memoize extend Annotation def memoize(func_name) aliased = "_orig_#{func_name}" # or "_#{func_name}_#{rand().to_s[2..9]}" alias_method aliased, func_name s = "def #{func_name}(*args) @_memos ||= {} hash = (@_memos[:#{func_name}] ||= {}) hash[args] = __send__(:#{aliased}, *args) unless hash.key?(args) return hash[args] end" class_eval s end annotation :memoize # !!!!!! end class Fib extend Memoize def fib1(n) n <= 2 ? 1 : fib1(n-1) + fib1(n-2) end memoize # !!!! def fib2(n) n <= 2 ? 1 : fib2(n-1) + fib2(n-2) end end require 'benchmark' fib = Fib.new Benchmark.bm(20) do |x| x.report('fib1(30)') { ret = fib.fib1(30) } x.report('fib2(30)') { ret = fib.fib2(30) } end ### Result: # $ ruby memoize.rb # user system total real # fib1(30) 1.060000 0.000000 1.060000 ( 1.063110) # fib2(30) 0.000000 0.000000 0.000000 ( 0.000327) ex3. obsolete.rb require 'annotation' module Obsolete extend Annotation def obsolete(method) aliased = "_orig_#{method}" # or "_#{method}_#{rand().to_s[2..9]}" alias_method aliased, method s = "def #{method}(*args) warn %Q`*** warning: #{method} is obsolete.` __send__(:#{aliased}, *args) end" class_eval s end annotation :obsolete # !!!!!! end class Hello extend Obsolete obsolete # !!!!!! def hello(name) puts "Hello #{name}!" end end Hello.new.hello('World') #=> *** warning: hello is obsolete. ex4. my_test.rb require 'test/unit' require 'annotation' module DummyFiles extend Annotation def dummy_files(method_name, files={}) aliased = "__#{method_name}_#{rand().to_s[2..10]}" alias_method aliased, method_name define_method method_name do begin files.each do |filename, content| next unless content File.open(filename, 'w') {|f| f.write(content) } end __send__(aliased) ensure files.each do |filename, _| File.unlink(filename) if File.exist?(filename) end end end end annotation :dummy_files # !!!!!! end class MyTestCase < Test::Unit::TestCase extend DummyFiles dummy_files 'A.txt'=>'AAA', 'B.txt'=>'BBB' # !!!!!! def test_something assert_equal 'AAA', File.read('A.txt') assert_equal 'BBB', File.read('B.txt') end end == Known Issues * Annotation and RDoc cannot be good friends. ## ...document... GET('/') # this annotation prevent RDoc to generate document! def index() ... end
About
small but useful annotation library for Ruby
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published