Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ahoward committed Jul 28, 2009
0 parents commit cbbe03e
Show file tree
Hide file tree
Showing 5 changed files with 456 additions and 0 deletions.
37 changes: 37 additions & 0 deletions README
@@ -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)'
228 changes: 228 additions & 0 deletions Rakefile
@@ -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)
}
128 changes: 128 additions & 0 deletions lib/shared.rb
@@ -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

0 comments on commit cbbe03e

Please sign in to comment.