Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit cbbe03e
Showing
5 changed files
with
456 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
NAME | ||
shared.rb | ||
|
||
DESCRIPTION | ||
shared.rb provides a super easy way to share code between classes or modules | ||
in a simple way. shared code can be at the class and/or instance level and | ||
users deferred evaluation so this is more powerful that the normal ruby | ||
module inclusion facilities on which it is based. | ||
|
||
SYNOPSIS | ||
require 'shared' | ||
|
||
Shared 'methods' do | ||
class << self | ||
attr :classname | ||
end | ||
|
||
@classname = name.downcase | ||
|
||
def objectname | ||
self.class.classname + "(#{ object_id })" | ||
end | ||
end | ||
|
||
class C | ||
include Shared('methods') | ||
end | ||
|
||
class B | ||
include Shared('methods') | ||
end | ||
|
||
p C.classname #=> 'c' | ||
p C.new.objectname #=> 'c(1234)' | ||
|
||
p B.classname #=> 'b' | ||
p B.new.objectname #=> 'b(4567)' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
|
||
This.rubyforge_project = 'codeforpeople' | ||
This.author = "Ara T. Howard" | ||
This.email = "ara.t.howard@gmail.com" | ||
This.homepage = "http://github.com/ahoward/#{ This.lib }/tree/master" | ||
|
||
|
||
task :default do | ||
puts(Rake::Task.tasks.map{|task| task.name} - ['default']) | ||
end | ||
|
||
|
||
task :gemspec do | ||
ignore_extensions = 'git', 'svn', 'tmp', /sw./, 'bak', 'gem' | ||
ignore_directories = 'pkg' | ||
ignore_files = 'test/log' | ||
|
||
shiteless = | ||
lambda do |list| | ||
list.delete_if do |entry| | ||
next unless test(?e, entry) | ||
extension = File.basename(entry).split(%r/[.]/).last | ||
ignore_extensions.any?{|ext| ext === extension} | ||
end | ||
list.delete_if do |entry| | ||
next unless test(?d, entry) | ||
dirname = File.expand_path(entry) | ||
ignore_directories.any?{|dir| File.expand_path(dir) == dirname} | ||
end | ||
list.delete_if do |entry| | ||
next unless test(?f, entry) | ||
filename = File.expand_path(entry) | ||
ignore_files.any?{|file| File.expand_path(file) == filename} | ||
end | ||
end | ||
|
||
lib = This.lib | ||
version = This.version | ||
files = shiteless[Dir::glob("**/**")] | ||
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)} | ||
has_rdoc = true #File.exist?('doc') | ||
test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb") | ||
|
||
extensions = This.extensions | ||
if extensions.nil? | ||
%w( Makefile configure extconf.rb ).each do |ext| | ||
extensions << ext if File.exists?(ext) | ||
end | ||
end | ||
extensions = [extensions].flatten.compact | ||
|
||
template = | ||
if test(?e, 'gemspec.erb') | ||
Template{ IO.read('gemspec.erb') } | ||
else | ||
Template { | ||
<<-__ | ||
## #{ lib }.gemspec | ||
# | ||
Gem::Specification::new do |spec| | ||
spec.name = #{ lib.inspect } | ||
spec.version = #{ version.inspect } | ||
spec.platform = Gem::Platform::RUBY | ||
spec.summary = #{ lib.inspect } | ||
spec.files = #{ files.inspect } | ||
spec.executables = #{ executables.inspect } | ||
spec.require_path = "lib" | ||
spec.has_rdoc = #{ has_rdoc.inspect } | ||
spec.test_files = #{ test_files.inspect } | ||
#spec.add_dependency 'lib', '>= version' | ||
#spec.add_dependency 'fattr' | ||
spec.extensions.push(*#{ extensions.inspect }) | ||
spec.rubyforge_project = #{ This.rubyforge_project.inspect } | ||
spec.author = #{ This.author.inspect } | ||
spec.email = #{ This.email.inspect } | ||
spec.homepage = #{ This.homepage.inspect } | ||
end | ||
__ | ||
} | ||
end | ||
|
||
open("#{ lib }.gemspec", "w"){|fd| fd.puts template} | ||
This.gemspec = "#{ lib }.gemspec" | ||
end | ||
|
||
task :gem => [:clean, :gemspec] do | ||
Fu.mkdir_p This.pkgdir | ||
before = Dir['*.gem'] | ||
cmd = "gem build #{ This.gemspec }" | ||
`#{ cmd }` | ||
after = Dir['*.gem'] | ||
gem = ((after - before).first || after.first) or abort('no gem!') | ||
Fu.mv gem, This.pkgdir | ||
This.gem = File.basename(gem) | ||
end | ||
|
||
task :readme do | ||
samples = '' | ||
prompt = '~ > ' | ||
lib = This.lib | ||
version = This.version | ||
|
||
Dir['sample*/*'].sort.each do |sample| | ||
samples << "\n" << " <========< #{ sample } >========>" << "\n\n" | ||
|
||
cmd = "cat #{ sample }" | ||
samples << Util.indent(prompt + cmd, 2) << "\n\n" | ||
samples << Util.indent(`#{ cmd }`, 4) << "\n" | ||
|
||
cmd = "ruby #{ sample }" | ||
samples << Util.indent(prompt + cmd, 2) << "\n\n" | ||
|
||
cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -Ilib #{ sample })'" | ||
samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n" | ||
end | ||
|
||
template = | ||
if test(?e, 'readme.erb') | ||
Template{ IO.read('readme.erb') } | ||
else | ||
Template { | ||
<<-__ | ||
NAME | ||
#{ lib } | ||
DESCRIPTION | ||
INSTALL | ||
gem install #{ lib } | ||
SAMPLES | ||
#{ samples } | ||
__ | ||
} | ||
end | ||
|
||
open("README", "w"){|fd| fd.puts template} | ||
end | ||
|
||
|
||
task :clean do | ||
Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)} | ||
end | ||
|
||
|
||
task :release => [:clean, :gemspec, :gem] do | ||
gems = Dir[File.join(This.pkgdir, '*.gem')].flatten | ||
raise "which one? : #{ gems.inspect }" if gems.size > 1 | ||
raise "no gems?" if gems.size < 1 | ||
cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.pkgdir }/#{ This.gem }" | ||
puts cmd | ||
system cmd | ||
end | ||
|
||
|
||
|
||
|
||
|
||
BEGIN { | ||
$VERBOSE = nil | ||
|
||
require 'ostruct' | ||
require 'erb' | ||
require 'fileutils' | ||
|
||
Fu = FileUtils | ||
|
||
This = OpenStruct.new | ||
|
||
This.file = File.expand_path(__FILE__) | ||
This.dir = File.dirname(This.file) | ||
This.pkgdir = File.join(This.dir, 'pkg') | ||
|
||
lib = ENV['LIB'] | ||
unless lib | ||
lib = File.basename(Dir.pwd) | ||
end | ||
This.lib = lib | ||
|
||
version = ENV['VERSION'] | ||
unless version | ||
name = lib.capitalize | ||
require "./lib/#{ lib }" | ||
version = eval(name).send(:version) | ||
end | ||
This.version = version | ||
|
||
abort('no lib') unless This.lib | ||
abort('no version') unless This.version | ||
|
||
module Util | ||
def indent(s, n = 2) | ||
s = unindent(s) | ||
ws = ' ' * n | ||
s.gsub(%r/^/, ws) | ||
end | ||
|
||
def unindent(s) | ||
indent = nil | ||
s.each do |line| | ||
next if line =~ %r/^\s*$/ | ||
indent = line[%r/^\s*/] and break | ||
end | ||
indent ? s.gsub(%r/^#{ indent }/, "") : s | ||
end | ||
extend self | ||
end | ||
|
||
class Template | ||
def initialize(&block) | ||
@block = block | ||
@template = block.call.to_s | ||
end | ||
def expand(b=nil) | ||
ERB.new(Util.unindent(@template)).result(b||@block) | ||
end | ||
alias_method 'to_s', 'expand' | ||
end | ||
def Template(*args, &block) Template.new(*args, &block) end | ||
|
||
Dir.chdir(This.dir) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# shared.rb provides a super easy way to share code between classes or modules | ||
# in a simple way. shared code can be at the class and/or instance level and | ||
# users deferred evaluation so this is more powerful that the normal ruby | ||
# module inclusion facilities on which it is based. | ||
# | ||
# basic usage: | ||
# | ||
# | ||
# require 'shared' | ||
# | ||
# Shared 'methods' do | ||
# class << self | ||
# attr :classname | ||
# end | ||
# | ||
# @classname = name.downcase | ||
# | ||
# def objectname | ||
# self.class.classname + "(#{ object_id })" | ||
# end | ||
# end | ||
# | ||
# class C | ||
# include Shared('methods') | ||
# end | ||
# | ||
# class B | ||
# include Shared('methods') | ||
# end | ||
# | ||
# p C.classname #=> 'c' | ||
# p C.new.objectname #=> 'c(1234)' | ||
# | ||
# p B.classname #=> 'b' | ||
# p B.new.objectname #=> 'b(4567)' | ||
# | ||
|
||
|
||
unless defined?(Shared) | ||
module Shared | ||
Shared::VERSION = '1.1.0' unless defined?(Shared::VERSION) | ||
def version() Shared::VERSION end | ||
|
||
Code = {} | ||
|
||
def load key | ||
key = key_for(key) | ||
unless Code.has_key?(key) | ||
::Kernel.load("shared/#{ key }.rb") | ||
end | ||
end | ||
|
||
def shared name, options = {}, &block | ||
key = key_for name | ||
via = (options[:via]||options['via']||:eval).to_s.to_sym | ||
|
||
if block.nil? | ||
Shared.load(key) | ||
return Code[key] | ||
end | ||
|
||
m = (Code[key] || Module.new) | ||
|
||
case via | ||
when :eval | ||
singleton_class(m) do | ||
unless m.respond_to?(:blocks) | ||
blocks = [] | ||
|
||
define_method(:blocks){ blocks } | ||
|
||
define_method(:included) do |other| | ||
blocks.each{|b| other.send(:module_eval, &b)} | ||
end | ||
|
||
define_method(:extend_object) do |other| | ||
Shared.singleton_class(other) do | ||
m.blocks.each{|b| module_eval &b} | ||
end | ||
end | ||
end | ||
end | ||
m.blocks << block | ||
|
||
when :module | ||
m.send(:module_eval, &block) | ||
end | ||
|
||
Code[key] ||= m | ||
end | ||
|
||
alias_method 'share', 'shared' | ||
alias_method 'for', 'shared' | ||
|
||
def key_for name | ||
name.to_s.strip.downcase | ||
end | ||
|
||
def singleton_class object, &block | ||
singleton_class = | ||
class << object | ||
self | ||
end | ||
block ? singleton_class.module_eval(&block) : singleton_class | ||
end | ||
|
||
extend self | ||
end | ||
|
||
module Kernel | ||
private | ||
def Share(*a, &b) | ||
if a.empty? and b.nil? | ||
::Shared | ||
else | ||
Shared.share(*a, &b) | ||
end | ||
end | ||
|
||
def Shared(*a, &b) | ||
if a.empty? and b.nil? | ||
::Shared | ||
else | ||
Shared.shared(*a, &b) | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.