I've been looking into ways how libraries and rails engines communicate deprecation warnings and found couple of surprising things. 

Everyone working with Rails probably heard or seen `ActiveSupport::Deprecation` in action. But what about gems that don't depend on any rails dependencies? `Kernel.warn` might surprise you here. 
## ActiveSupport::Deprecation
Rails offers a no thrills way to emit deprecation warnings, that everyone already knows about.

Before Rails 7.1 it would look like this:

```ruby
ActiveSupport::Deprecation.warn("Method will be removed in next version")

# or
deprecator = ActiveSupport::Deprecation.new("2.0", "MyGem")
deprecator.warn("Method will be removed in next version")
```

But starting with Rails 7.1 explicit deprecators registry became a thing. So things became even simpler.
```ruby
Rails.deprecator.warn("Method will be removed in next version")

# or for specific gems

Rails.deprecators[:my_gem].warn("Method will be removed in next version")

```

How these deprecations are communicated can be configured with `config.active_support.deprecation` setting .

| Value    | Result                                                         |
| -------- | -------------------------------------------------------------- |
| :raise   | Raise ActiveSupport::DeprecationException                      |
| :stderr  | Logs all deprecation warnings to `$stderr`                     |
| :log     | Logs all deprecation warnings to Rails.logger                  |
| :notify  | Use ActiveSupport::Notifications to notify `deprecation.rails` |
| :report  | Use ActiveSupport::ErrorReporter to report deprecations        |
| :silence | Do nothing                                                     |

There is also a way to include stack trace with every warning if you enable debug mode.

```ruby
Rails.application.deprecators.debug = true
```

Everything seems pretty clear and simple here. But what if you don't depend on active support?
## Kernel.warn
Turns out, that `Kernel.warn` is not just a generic method to emit warnings. `Kernel.warn` doubles down as a way to communicate deprecation's, experimental features or performance improvements.

There are two downsides though:
1. It's not very well documented, so hardly anyone knows.
2. Deprecation warnings are silenced by default

But here is way to emit a deprecation warning:
```ruby
warn("Method is deprecated", category: :deprecated)
```

Problem is that nobody is likely to be listening. Since default values for each category are as follows:

- `Warning[:deprecated] # => false`
- `Warning[:experimental] # => true`
- `Warning[:performance] # => false`

Warning and performance categories are silenced by default. But off course this could be changed by setting `Warning[:deprecated] = true` or using `-W` argument in RUBYOPTS. 

`export RUBYOPT="-W1:deprecated"`

Or you can ask ruby to be more verbose and this will enable all warning categories:

`export RUBYOPTS="-W2"`

I'm hunting for deprecation's, but performance improvement warnings can give a lot of nice hints and are worth exploring too.