Forum: Ruby final/closed classes in Ruby (was: Sharp knives and glue)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
F3b7b8756d0c7f71cc7460cc33aefaee?d=identicon&s=25 Berger, Daniel (Guest)
on 2006-05-11 23:28
(Received via mailing list)
The 'Sharp knives and glue' thread inspired this.  It's probably been
done before but here's my implementation of a final and/or closed class:

# Make a class unsubclassable
class Class
   def final(klass)
      class << klass
         def inherited(subclass)
            error = "Illegal attempt to subclass #{self} with
#{subclass}"
            raise RuntimeError, error
         end
      end
   end
end

class Foo
   final(self) # No subclasses allowed
end

# Boom!
class Bar < Foo
end

# Close a class (no method definitions or redefinitions)

class Module
   def close(klass)
      class << self
         def method_added(method)
            error = "cannot add or change method #{method} to closed"
            error += " class #{self}"
            raise RuntimeError, error
         end
      end
   end
end

class Foo
   def test
      puts "hello"
   end
   close(self) # No method additions/redefinitions allowed
end

# Boom!
class Foo
   def test2
      puts "eh?"
   end
end

This could probably be combined into a single method, and perhaps put in
the Kernel module as well.

Anyway, there you have it.

Regards,

Dan


This communication is the property of Qwest and may contain confidential
or
privileged information. Unauthorized use of this communication is
strictly
prohibited and may be unlawful.  If you have received this communication
in error, please immediately notify the sender by reply e-mail and
destroy
all copies of the communication and any attachments.
Bf6862e2a409078e13a3979c00bba1d6?d=identicon&s=25 Gregory Seidman (Guest)
on 2006-05-11 23:40
(Received via mailing list)
On Fri, May 12, 2006 at 06:27:13AM +0900, Berger, Daniel wrote:
} The 'Sharp knives and glue' thread inspired this.  It's probably been
} done before but here's my implementation of a final and/or closed
class:
}
} # Make a class unsubclassable
[...]
} # Close a class (no method definitions or redefinitions)
[...]
} class Foo
}    def test
}       puts "hello"
}    end
}    close(self) # No method additions/redefinitions allowed
} end
[...]

class Foo
  def test
    puts "hello"
  end
  freeze #this already exists and does what you want
end

} Regards,
} Dan
--Greg
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-12 01:18
(Received via mailing list)
On May 11, 2006, at 5:27 PM, Berger, Daniel wrote:

> #{subclass}"
> # Boom!
> class Bar < Foo
> end

Has potential, but why not just do:

class Class
   def final # or even final!
     class << self
       def inherited(subclass)
         error = "Illegal attempt to subclass #{self} with
#{subclass}"
         raise RuntimeError, error
       end
     end
   end
end

class Foo
   final
end

class Bar < Foo
end

RuntimeError: Illegal attempt to subclass Foo with
Bar
         from (irb):7:in `inherited'
         from (irb):17

Unfortunately, it raises an exception way too late.

try:

class Foo
   final
end

begin
class Bar < Foo
end
# Foo.inherited(Bar) pretty much happens here
rescue
end

b = Bar.new
This topic is locked and can not be replied to.