├── var ├── version ├── license ├── name ├── organization ├── title ├── subtitle ├── authors ├── copyrights ├── summary ├── repositories ├── requirements ├── description └── resources ├── Gemfile ├── test ├── helper.rb └── case_main_like_module.rb ├── .gitignore ├── MANIFEST ├── .travis.yml ├── HISTORY.md ├── .test ├── Assembly ├── README.md ├── .ruby ├── NOTICE.md ├── lib └── main_like_module.rb └── .gemspec /var/version: -------------------------------------------------------------------------------- 1 | 0.1.0 2 | -------------------------------------------------------------------------------- /var/license: -------------------------------------------------------------------------------- 1 | BSD-2-Clause 2 | -------------------------------------------------------------------------------- /var/name: -------------------------------------------------------------------------------- 1 | main_like_module 2 | -------------------------------------------------------------------------------- /var/organization: -------------------------------------------------------------------------------- 1 | Rubyworks 2 | -------------------------------------------------------------------------------- /var/title: -------------------------------------------------------------------------------- 1 | Main Like Module 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | gemspec 3 | -------------------------------------------------------------------------------- /var/subtitle: -------------------------------------------------------------------------------- 1 | The Way Main Should Be 2 | -------------------------------------------------------------------------------- /var/authors: -------------------------------------------------------------------------------- 1 | --- 2 | - trans 3 | 4 | -------------------------------------------------------------------------------- /var/copyrights: -------------------------------------------------------------------------------- 1 | --- 2 | - (c) 2006 Rubyworks (BSD-2-Clause) 3 | -------------------------------------------------------------------------------- /var/summary: -------------------------------------------------------------------------------- 1 | Completing the Object class proxy of toplevel. 2 | -------------------------------------------------------------------------------- /test/helper.rb: -------------------------------------------------------------------------------- 1 | require 'ae' 2 | require 'citron' 3 | 4 | require 'main_like_module' 5 | -------------------------------------------------------------------------------- /var/repositories: -------------------------------------------------------------------------------- 1 | --- 2 | upstream: git://github.com/rubyworks/main_like_module.git 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .reap/digest 2 | .yardoc 3 | doc 4 | log 5 | pkg 6 | tmp 7 | web 8 | work/sandbox 9 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | #!mast .ruby bin demo lib man qed spec test [A-Z]*.* 2 | .ruby 3 | lib/main_like_module.rb 4 | README.md 5 | -------------------------------------------------------------------------------- /var/requirements: -------------------------------------------------------------------------------- 1 | --- 2 | - detroit (build) 3 | - reap (build) 4 | - citron (test) 5 | - ae (test) 6 | 7 | -------------------------------------------------------------------------------- /var/description: -------------------------------------------------------------------------------- 1 | Main Like Module completes the toplevel proxy of 2 | the Object class, making the toplevel behave just 3 | as if it were a module context. 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | script: "bundle exec rubytest" 3 | rvm: 4 | - 1.8.7 5 | - 1.9.2 6 | - 1.9.3 7 | - rbx 8 | - rbx-19mode 9 | - jruby 10 | - jruby-19mode 11 | 12 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # RELEASE HISTORY 2 | 3 | ## 0.1.0 / 2011-12-23 4 | 5 | Initial and quite hopefully the only release ever needed. 6 | 7 | Changes: 8 | 9 | * Spun project off from Ruby Facets. 10 | 11 | -------------------------------------------------------------------------------- /var/resources: -------------------------------------------------------------------------------- 1 | --- 2 | home: http://rubyworks.github.com/main_like_module 3 | code: http://github.com/rubyworks/main_like_module 4 | bugs: http://github.com/rubyworks/main_like_module/issues 5 | mail: http://groups.google.com/groups/rubyworks-mailinglist 6 | 7 | -------------------------------------------------------------------------------- /test/case_main_like_module.rb: -------------------------------------------------------------------------------- 1 | require 'helper' 2 | 3 | testcase "Main Like Module" do 4 | 5 | test :define_method do 6 | eval <<-END, TOPLEVEL_BINDING 7 | define_method(:just_some_method) do 8 | 'just some method' 9 | end 10 | END 11 | just_some_method.assert == 'just some method' 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /.test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'ae' 4 | require 'citron' 5 | 6 | $:.unshift('./test') 7 | 8 | # Default test run. 9 | Test.run do |r| 10 | r.files << 'test' 11 | end 12 | 13 | # Generate SimpleCov coverage report. 14 | # Albeit, it probably won't do this project much good. 15 | Test.run :cov do |r| 16 | r.files << 'test' 17 | require 'simplecov' 18 | SimpleCov.start do 19 | coverage_dir 'log/coverage' 20 | add_filter "/test/" 21 | end 22 | end 23 | 24 | -------------------------------------------------------------------------------- /Assembly: -------------------------------------------------------------------------------- 1 | --- 2 | gem: 3 | active: true 4 | 5 | github: 6 | gh_pages: web 7 | 8 | email: 9 | mailto: 10 | - ruby-talk@ruby-lang.org 11 | - rubyworks-mailinglist@googlegroups.com 12 | 13 | locat: 14 | output: log/locat.html 15 | active: false 16 | 17 | vclog: 18 | output: 19 | - log/changes.html 20 | - log/history.html 21 | active: false 22 | 23 | 24 | # TODO: Use rubytest tool when ready 25 | #lemon: 26 | # tool : Custom 27 | # track : main 28 | # test: | 29 | # sh 'ruby-test test' 30 | # active: false 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Main Like Module 2 | 3 | [![Build Status](https://secure.travis-ci.org/rubyworks/main_like_module.png)](http://travis-ci.org/rubyworks/main_like_module) 4 | 5 | 6 | __DESCRIPTION__ 7 | 8 | Did you know `main`? Main is actually the special name Ruby gives 9 | to the toplevel object. This object is very special, it is actually 10 | in part a proxy object for the Object class itself. But it's only 11 | a partial implementation. 12 | 13 | I have long argued that the toplevel object should be replaced with 14 | an self extended module, e.g. 15 | 16 | module Toplevel 17 | extend self 18 | # ruby is executed here 19 | end 20 | 21 | This would have a couple of significant benefits. First, the toplevel 22 | would no longer pollute every other object in the system. And second, 23 | the toplevel would be a fully operational module context. 24 | 25 | Alas, so far, no avail. But there's always hope. In the mean time, 26 | we can at least support the second point by completing the proxy, 27 | making it emulate the Object class context in full. And that's 28 | exactly what Main Like Module does. 29 | 30 | 31 | __COPYRIGHTS__ 32 | 33 | Copyright (c) 2009 Rubyworks 34 | 35 | Main as Module is distributable in accordance with the BSD-2-Clause license. 36 | 37 | See COPYING.md for details. 38 | 39 | -------------------------------------------------------------------------------- /.ruby: -------------------------------------------------------------------------------- 1 | --- 2 | source: 3 | - var 4 | authors: 5 | - name: trans 6 | email: transfire@gmail.com 7 | copyrights: 8 | - holder: Rubyworks 9 | year: '2006' 10 | license: BSD-2-Clause 11 | replacements: [] 12 | alternatives: [] 13 | requirements: 14 | - name: detroit 15 | groups: 16 | - build 17 | development: true 18 | - name: reap 19 | groups: 20 | - build 21 | development: true 22 | - name: citron 23 | groups: 24 | - test 25 | development: true 26 | - name: ae 27 | groups: 28 | - test 29 | development: true 30 | dependencies: [] 31 | conflicts: [] 32 | repositories: 33 | - uri: git://github.com/rubyworks/main_like_module.git 34 | scm: git 35 | name: upstream 36 | resources: 37 | home: http://rubyworks.github.com/main_like_module 38 | code: http://github.com/rubyworks/main_like_module 39 | bugs: http://github.com/rubyworks/main_like_module/issues 40 | mail: http://groups.google.com/groups/rubyworks-mailinglist 41 | extra: {} 42 | load_path: 43 | - lib 44 | revision: 0 45 | summary: Completing the Object class proxy of toplevel. 46 | title: Main Like Module 47 | version: 0.1.0 48 | name: main_like_module 49 | description: ! 'Main Like Module completes the toplevel proxy of 50 | 51 | the Object class, making the toplevel behave just 52 | 53 | as if it were a module context.' 54 | organization: Rubyworks 55 | date: '2011-12-23' 56 | -------------------------------------------------------------------------------- /NOTICE.md: -------------------------------------------------------------------------------- 1 | Main Like Module 2 | 3 | Copyright (c) 2011 Rubyworks. All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are 6 | permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of 9 | conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | of conditions and the following disclaimer in the documentation and/or other materials 13 | provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY Rubyworks ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Rubyworks OR 18 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 22 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /lib/main_like_module.rb: -------------------------------------------------------------------------------- 1 | # Main like Module 2 | # 3 | # Main, ie. the top-level object, is not fully in-sync with 4 | # Module. So, certain methods like #define_method do not work. 5 | # This library fixes this. 6 | # 7 | # Techinally it is this authors opinion that the top-level object 8 | # most likely would be better-off as a self-extended module, and 9 | # methods defined in it do not automatically get added to the 10 | # Object class. 11 | # 12 | # On the other hand. It is probably best to never use the toplevel 13 | # except as a jumping in point to youre own namespace. 14 | # 15 | # Note that none of this would be needed if Main were just a self extended 16 | # module. 17 | 18 | def_meth = Proc.new do |m| 19 | if /=$/ =~ m.to_s 20 | eval <<-END 21 | def self.#{m}(arg) 22 | Object.class_eval do 23 | #{m}(arg) 24 | end 25 | end 26 | END 27 | else 28 | eval <<-END 29 | def self.#{m}( *args, &block ) 30 | Object.class_eval do 31 | #{m}( *args, &block ) 32 | end 33 | end 34 | END 35 | end 36 | end 37 | 38 | public 39 | 40 | (Module.public_instance_methods - public_methods).each do |m| 41 | next if m == "initialize" 42 | next if m =~ /^\W+$/ 43 | def_meth[m] 44 | end 45 | 46 | private 47 | 48 | (Module.private_instance_methods - private_methods).each do |m| 49 | next if m == "initialize" 50 | next if m =~ /^\W+$/ 51 | def_meth[m] 52 | end 53 | 54 | protected 55 | 56 | (Module.protected_instance_methods - protected_methods).each do |m| 57 | next if m == "initialize" 58 | next if m =~ /^\W+$/ 59 | def_meth[m] 60 | end 61 | 62 | # Copyright (c) 2006 Thomas Sawyer (Ruby License) 63 | -------------------------------------------------------------------------------- /.gemspec: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'yaml' 4 | 5 | module DotRuby 6 | 7 | # 8 | class GemSpec 9 | 10 | # For which revision of .ruby is this gemspec intended? 11 | REVISION = 0 unless defined?(REVISION) 12 | 13 | # 14 | PATTERNS = { 15 | :bin_files => 'bin/*', 16 | :lib_files => 'lib/{**/}*.rb', 17 | :ext_files => 'ext/{**/}extconf.rb', 18 | :doc_files => '*.{txt,rdoc,md,markdown,tt,textile}', 19 | :test_files => '{test/{**/}*_test.rb,spec/{**/}*_spec.rb}' 20 | } unless defined?(PATTERNS) 21 | 22 | # 23 | def self.instance 24 | new.to_gemspec 25 | end 26 | 27 | attr :metadata 28 | 29 | attr :manifest 30 | 31 | # 32 | def initialize 33 | @metadata = YAML.load_file('.ruby') 34 | @manifest = Dir.glob('manifest{,.txt}', File::FNM_CASEFOLD).first 35 | 36 | if @metadata['revision'].to_i != REVISION 37 | warn "You have the wrong revision. Trying anyway..." 38 | end 39 | end 40 | 41 | # 42 | def scm 43 | @scm ||= \ 44 | case 45 | when File.directory?('.git') 46 | :git 47 | end 48 | end 49 | 50 | # 51 | def files 52 | @files ||= \ 53 | #glob_files[patterns[:files]] 54 | case 55 | when manifest 56 | File.readlines(manifest). 57 | map{ |line| line.strip }. 58 | reject{ |line| line.empty? || line[0,1] == '#' } 59 | when scm == :git 60 | `git ls-files -z`.split("\0") 61 | else 62 | Dir.glob('{**/}{.*,*}') # TODO: be more specific using standard locations ? 63 | end.select{ |path| File.file?(path) } 64 | end 65 | 66 | # 67 | def glob_files(pattern) 68 | Dir.glob(pattern).select { |path| 69 | File.file?(path) && files.include?(path) 70 | } 71 | end 72 | 73 | # 74 | def patterns 75 | PATTERNS 76 | end 77 | 78 | # 79 | def executables 80 | @executables ||= \ 81 | glob_files(patterns[:bin_files]).map do |path| 82 | File.basename(path) 83 | end 84 | end 85 | 86 | def extensions 87 | @extensions ||= \ 88 | glob_files(patterns[:ext_files]).map do |path| 89 | File.basename(path) 90 | end 91 | end 92 | 93 | # 94 | def name 95 | metadata['name'] || metadata['title'].downcase.gsub(/\W+/,'_') 96 | end 97 | 98 | # 99 | def to_gemspec 100 | Gem::Specification.new do |gemspec| 101 | gemspec.name = name 102 | gemspec.version = metadata['version'] 103 | gemspec.summary = metadata['summary'] 104 | gemspec.description = metadata['description'] 105 | 106 | metadata['authors'].each do |author| 107 | gemspec.authors << author['name'] 108 | 109 | if author.has_key?('email') 110 | if gemspec.email 111 | gemspec.email << author['email'] 112 | else 113 | gemspec.email = [author['email']] 114 | end 115 | end 116 | end 117 | 118 | gemspec.licenses = metadata['copyrights'].map{ |c| c['license'] }.compact 119 | 120 | metadata['requirements'].each do |req| 121 | name = req['name'] 122 | version = req['version'] 123 | groups = req['groups'] || [] 124 | 125 | case version 126 | when /^(.*?)\+$/ 127 | version = ">= #{$1}" 128 | when /^(.*?)\-$/ 129 | version = "< #{$1}" 130 | when /^(.*?)\~$/ 131 | version = "~> #{$1}" 132 | end 133 | 134 | if groups.empty? or groups.include?('runtime') 135 | # populate runtime dependencies 136 | if gemspec.respond_to?(:add_runtime_dependency) 137 | gemspec.add_runtime_dependency(name,*version) 138 | else 139 | gemspec.add_dependency(name,*version) 140 | end 141 | else 142 | # populate development dependencies 143 | if gemspec.respond_to?(:add_development_dependency) 144 | gemspec.add_development_dependency(name,*version) 145 | else 146 | gemspec.add_dependency(name,*version) 147 | end 148 | end 149 | end 150 | 151 | # convert external dependencies into a requirements 152 | if metadata['external_dependencies'] 153 | ##gemspec.requirements = [] unless metadata['external_dependencies'].empty? 154 | metadata['external_dependencies'].each do |req| 155 | gemspec.requirements << req.to_s 156 | end 157 | end 158 | 159 | # determine homepage from resources 160 | homepage = metadata['resources'].find{ |key, url| key =~ /^home/ } 161 | gemspec.homepage = homepage.last if homepage 162 | 163 | gemspec.require_paths = metadata['load_path'] || ['lib'] 164 | gemspec.post_install_message = metadata['install_message'] 165 | 166 | # RubyGems specific metadata 167 | gemspec.files = files 168 | gemspec.extensions = extensions 169 | gemspec.executables = executables 170 | 171 | if Gem::VERSION < '1.7.' 172 | gemspec.default_executable = gemspec.executables.first 173 | end 174 | 175 | gemspec.test_files = glob_files(patterns[:test_files]) 176 | 177 | unless gemspec.files.include?('.document') 178 | gemspec.extra_rdoc_files = glob_files(patterns[:doc_files]) 179 | end 180 | end 181 | end 182 | 183 | end #class GemSpec 184 | 185 | end 186 | 187 | DotRuby::GemSpec.instance 188 | --------------------------------------------------------------------------------