Project

finalist

0.01
No commit activity in last 3 years
No release in over 3 years
Add final syntax which forbids method override
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.16
>= 0
~> 10.0
~> 3.0
 Project Readme

Finalist

Build Status Gem Version

Finalist adds final method modifier. final forbids method override.

This gem is pseudo static code analyzer by method_added and singleton_method_added and included and extended.

it detect final violation when class(module) is defined, not runtime.

Simple case is following.

class A1
  extend Finalist

  final def foo
  end
end

class A2 < A1
  def foo # => raise
  end
end

This case raises Finalist::OverrideFinalMethodError at def foo in A2 class.

This gem supports other cases. (see finalist_spec.rb)

My similar gems

Requirements

  • ruby-2.5.0 or later (depend on UnbountMethod#super_method behavior)

Installation

Add this line to your application's Gemfile:

gem 'finalist'

And then execute:

$ bundle

Or install it yourself as:

$ gem install finalist

Usage

A class or module extends Finalist module And add final modifier to target method. (final can accept symbol as method name.)

for Production

If you want to disable Finalist, write Finalist.disable = true at first line.

Examples

include module

module E1
  extend Finalist

  final def foo
  end
end

module E2
  include E1
end

module E3
  include E2

  def foo # => raise
  end
end

include module after override

module F1
  extend Finalist

  final def foo
  end
end

class F2
  def foo
  end

  include F1 # => raise
end

class method

class J1
  extend Finalist

  class << self
    final def foo
    end
  end
end

class J2 < J1
  class << self
    def foo # => raise
    end
  end
end

extend object

module H1
  extend Finalist

  final def foo
  end
end

a = "str"
a.extend(H1)
def a.foo # => raise
end

extend object after override

module I1
  extend Finalist

  final def foo
  end
end

a = "str"
def a.foo
end
a.extend(I1) # => raise

class method by extend module

module K1
  extend Finalist

  final def foo
  end
end

class K2
  extend K1

  class << self
    def foo # => raise
    end
  end
end

class method by extend module after override

module L1
  extend Finalist

  final def foo
  end
end

class L2
  class << self
    def foo
    end
  end

  extend L1 # => raise
end

overrided by module prepend

This case is a intended loophole.

module M1
  extend Finalist

  final def foo
  end
end

module M3
  def foo
    "foo"
  end
end

class M2
  include M1
  prepend M3
end

M2.new.foo # => "foo"

How is this implemented?

Use so many ruby hooks. method_added and singleton_method_added and included and extended.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/joker1007/finalist.

License

The gem is available as open source under the terms of the MIT License.