1 of 50

Suppress Warnings

15th, Sep. 2019�大阪Ruby会議02

2 of 50

pp self

3 of 50

Recently we released Kibela Web API

4 of 50

Goal of this talk

  • You can:
    • Find bugs with warnings.
    • Reduce warnings from your applications.
    • Create patches to OSS to suppress warnings.

5 of 50

Introduce Warning

6 of 50

What is the warning?

  • Ruby warns code, if
    • It may have a bug.
    • It is deprecated.
  • For example:
    • Useless variable: x = 1; p y
    • Deprecated method: File.exists?
      • Use File.exist? instead.

7 of 50

Warning levels

  • Ruby has 3 levels for warning.
  • Level 0: All warnings are disabled.
  • Level 1: Only important warnings are enabled (default).
  • Level 2: All warnings are enabled.
    • Almost warnings are enabled only with Level 2.

8 of 50

How to enable all warnings

  • `-w` option enables all warnings.
    • The level 2
  • $ ruby -e 42
    • Print nothing
  • $ ruby -w -e 42
    • -e:1: warning: possibly useless use of a literal in void context

9 of 50

Enable warnings without CLI option

  • We can also use RUBYOPT environment variable.
  • RUBYOPT is parsed as Ruby’s command line option.
  • RUBYOPT=-w bin/rails s
  • $ echo ‘export RUBYOPT=”-w”’ >> ~/.bashrc

10 of 50

What can we do with warning?

11 of 50

With warning, we can:

  • We can find bugs with warning.
  • We can contribute to OSS easier.

12 of 50

Find bugs

  • Ruby warns possible bug code.
  • If you solve a warning, a bug may be solved.

13 of 50

Contribute to OSS easier

  • Warning is easy to fix, in many cases.
  • Because
    • The goal is clear.
    • The patch will be small.
  • But some warnings is difficult to fix. e.g.
    • Uninitialized instance variable
    • The code has bug(s).

14 of 50

Why should we fix warnings?

15 of 50

Why should we fix warnings?

  • We can find bugs with warnings.
  • But if application has too many warnings, it is too difficult.
  • Similar with “Broken Windows Theory”.

16 of 50

17 of 50

Warning examples

18 of 50

Warnings examples

  • Let’s look warning with real pull requests.
    • Warning meaning.
    • How to fix warning.
    • What problems is found by the warning.

19 of 50

Deprecated method

cookpad/rrrspec#76

20 of 50

Deprecated method

  • File.exists?(path)
    • File.exists? is a deprecated name, use File.exist? instead
  • Dir.exists?(path)
    • Dir.exists? is a deprecated name, use Dir.exist? instead

Let’s look the pull request!

21 of 50

22 of 50

Part of the patch

- unless Dir.exists?(packaging_dir)+ unless Dir.exist?(packaging_dir)

23 of 50

Overview

  • File.exists? and Dir.exists? are deprecated.
  • It should be replaced with File.exist?.
  • It does not change any behavior.

24 of 50

It is one of the easiest warning!

  • Good for first step of pull request!
  • Because
    • Fixing approach is obvious.
    • It does not change any behavior.
  • But it has only small impact.

25 of 50

Other deprecated methods

  • Kernel.#open for URI. (In Ruby 2.7.0-dev)
    • Use URI.open.
      • File.open, IO.open, and IO.popen are also avairable.
  • URI.escape
    • Use ERB::Util.#url_encode, CGI.escape, or URI.encode_www_form_component
    • It depends on the requirement.

26 of 50

Method redefined

whitequark/parser#378

27 of 50

Method Redefined

  • def foo; end # It is ignored�def foo; end
    • warning: method redefined; discarding old foo

Let’s look the pull request!

28 of 50

29 of 50

Patch

30 of 50

Overview

  • Two methods ware accidently redefined in minitest test file.
  • A method has the same content, so I removed it.
  • But the other one has different method body.

31 of 50

In another case

  • If you really want to redefine method,�use remove_method.
    • remove_method :foo�def foo; end
    • e.g. https://github.com/ruby/irb/pull/18

32 of 50

duplicated when clause

thoughtbot/capybara-webkit#1068

33 of 50

Duplicated when clause

  • case x�when 1, 2, 1�end
    • duplicated `when' clause with line 2 is ignored

34 of 50

35 of 50

Part of the patch

36 of 50

Character class has

duplicated range

rouge-ruby/rouge#1197

37 of 50

Character class has duplicated range

  • /[aa]/
    • “a” is duplicated.
  • /[\w_]/
    • “\w” includes “_”.
  • /[\s\n]/
    • “\s” includes new line.
  • /[*+-=]/
    • It means “*” and chars between “+” and “=”.

38 of 50

39 of 50

40 of 50

Part of the patch (1)

41 of 50

Part of the patch (2)

42 of 50

Part of the patch (3)

43 of 50

Overview

  • Ruby also warns Regexp.
  • In this pull request, I found and fixed bugs.
    • → It is useful warning to find bug.
  • I often find the same warning from validations in app/models/user.rb.

44 of 50

instance variable not initialized

mizzy/specinfra#685

45 of 50

Instance variable not initialized

  • 🙆: def foo� @foo ||= something� end
  • 🙅: def foo� @foo ? @foo : something� end
    • instance variable @foo not initialized

46 of 50

47 of 50

Patch

48 of 50

Other solutions

  • Use ||=
    • @foo ||= something # It is OK
  • Use defined?
    • defined?(@foo) ? @foo : something

49 of 50

Conclusion

50 of 50

Conclusion

  • We looked warnings examples.
    • Meanings, how to fix warnings, etc
  • With using warnings, we can
    • Find bugs.
    • Contribute to OSS easier.
  • Let’s try enabling warnings in your application!

Thank you for listening!