Fwd: Is anyone using -w?

I’ve been wanting to use -w … However, I found out that quite a few
high-profile gems out there are not clean under -w (e.g. pry), meaning
that
I have a hard time using -w myself.

How many people actually do use -w ? Is this really a “best practice”
in
the ruby world these days ?

Sylvain

On Jun 23, 2014, at 4:30, Sylvain J.
[email protected] wrote:

I’ve been wanting to use -w … However, I found out that quite a few
high-profile gems out there are not clean under -w (e.g. pry), meaning that I have
a hard time using -w myself.

How many people actually do use -w ? Is this really a “best practice” in the
ruby world these days ?

FWIW, both tenderlove and I have all our libraries -w clean. Many of us
do, but it only takes one bad apple to ruin it for all your work. :confused:

We started warningfree · GitHub to try to address this, but we
could really use contributions (Sadly, there are way more of them than
there are of us).

Hi guys,

what is -w? It’s incredible hard to Google :slight_smile:

On Jun 23, 2014, at 23:27, Adam W. [email protected] wrote:

Hi guys,

what is -w? It’s incredible hard to Google :slight_smile:

% ruby -h
Usage: ruby [switches] [–] [programfile] [arguments]
-0[octal] specify record separator (\0, if no argument)
-a autosplit mode with -n or -p (splits $_ into $F)
-c check syntax only
-Cdirectory cd to directory before executing your script
-d set debugging flags (set $DEBUG to true)
-e ‘command’ one line of script. Several -e’s allowed. Omit
[programfile]
-Eex[:in] specify the default external and internal character
encodings
-Fpattern split() pattern for autosplit (-a)
-i[extension] edit ARGV files in place (make backup if extension
supplied)
-Idirectory specify $LOAD_PATH directory (may be used more than
once)
-l enable line ending processing
-n assume ‘while gets(); … end’ loop around your script
-p assume loop like -n but print line also like sed
-rlibrary require the library before executing your script
-s enable some switch parsing for switches after script
name
-S look for the script using PATH environment variable
-T[level=1] turn on tainting checks
-v print version number, then turn on verbose mode
-w turn warnings on for your script
-W[level=2] set warning level; 0=silence, 1=medium, 2=verbose
-x[directory] strip off text before #!ruby line and perhaps cd to
directory
-h show this message, --help for more info

Thanks Ryan. I have 3 few follow-up questions if you have time:

What does it mean to make your library -w clean?
What are the benefits/drawbacks of doing so?
I would like start contributing to OS, and your warningfree project looks
like something I might be interested in. I might need a little guidance
to
get started. (I consider myself to be an advanced beginner/competent
Rubyist
(Dreyfus model of skill acquisition - Wikipedia).) Do
you think this might be something I could help out with?

Thanks in advance for your advice.
Adam

On Jun 24, 2014, at 0:37, Adam W. [email protected] wrote:

Thanks Ryan. I have 3 few follow-up questions if you have time:

What does it mean to make your library -w clean?

A number of specific things:

  • Methods aren’t redefined accidentally.
  • Variables are initialized before they’re used.
  • Variables (all sorts) are used at least once after initialization.
  • Variables (all sorts) don’t shadow outer variables.
  • Regexps have clean ranges & escapes.
  • Format strings match their args.

There might be more. I’m tired and don’t remember.

What are the benefits/drawbacks of doing so?

The benefits should be pretty clear:

  • I can use your library in my app and my tests will still run clean
    with -w (which means MY code can be -w). IOW, nobody is pissing in the
    public pool.

  • You get certain assurances about a library that you know is warning
    free: instance variables are assigned before being used, block variables
    aren’t shadowing, code has been cleaned up and/or typos are fixed,
    etc… IOW, the author(s) cared about and paid attention to the design
    and quality of their code.

  • A warning-free library is a better ruby citizen.

The drawbacks?

Honestly, I don’t care. I’ll pay the price to put out cleaner code. I
think it is well worth it.

Some have claimed that there are speed benefits to writing sloppier
code. I have yet to see anything truly rigorous and definitive.

I would like start contributing to OS, and your warningfree project looks like
something I might be interested in. I might need a little guidance to get started.
(I consider myself to be an advanced beginner/competent Rubyist
(Dreyfus model of skill acquisition - Wikipedia).) Do you think
this might be something I could help out with?

Fixing up messy libraries is pretty tedious and doesn’t teach much as a
skill (other than what not to do). It does provide the ability to read
through some popular libraries and study their guts… So that really
depends on what you’re looking for.

Thanks Ryan, that actually sounds pretty interesting to me. I don’t
really
know where to start though, so how could I get involved?

On Jun 25, 2014, at 0:01, Adam W. [email protected] wrote:

Thanks Ryan, that actually sounds pretty interesting to me. I don’t really know
where to start though, so how could I get involved?

Run your tests with -w. Do something when they don’t run clean. Start
with simple pull requests.

This is a bit my problem as well. Maybe there is a need to be able to
turn
some warnings on or off depending on the application (as most compilers
allow these days).

Sylvain

2014-06-25 13:44 GMT+02:00 Wayne C. [email protected]:

On 06/23/2014 04:30 AM, Sylvain J. wrote:

How many people actually do use -w ? Is this really a “best
practice” in the ruby world these days ?

I do not attempt to write “-w clean” code, or even use -w, because:

 wayne@mercury:~$ irb -w
 2.1.1 :001 > class Foo
 2.1.1 :002?>   private
 2.1.1 :003?>   attr_accessor :bar
 2.1.1 :004?>   end
 (irb):3: warning: private attribute?

There is occasionally a valid reason to make a private
accessor/reader/writer, and no harm that I know of.

I think the only good choices are “-w clean” or don’t use -w. If I used
“-w” and then ignored some warnings, I would get so used to seeing the
warnings that I soon wouldn’t notice it when a warning I cared about
popped up. It would also send a strange message to someone running
tests on my code: “why does this test turn on -w and yet emit warnings?
Does this guy just not care?”

  • Wayne C.

On Wed, Jun 25, 2014 at 12:44 PM, Wayne C. [email protected] wrote:

2.1.1 :002?>   private
2.1.1 :003?>   attr_accessor :bar
2.1.1 :004?>   end
(irb):3: warning: private attribute?

There is occasionally a valid reason to make a private
accessor/reader/writer, and no harm that I know of.

There are definitely valid reasons for wanting private/protected
accessors
– I’m not sure why ruby gives a warning there, but it may just be that
it’s
easy to add the accessor in the wrong place – or it can be non-obvious
to a
reader that it is private.

If you definitely want a private accessor/reader/writer, you can tell
ruby
like this:

class Foo
attr_accessor :bar
private :bar
end

… and that is warning clean.

On 06/25/2014 04:53 AM, Sylvain J. wrote:

This is a bit my problem as well. Maybe there is a need to be able to
turn some warnings on or off depending on the application (as most
compilers allow these days).

I wondered what it would be like if Ruby had something like C++ #pragma
directives to enable/disable specific warnings. I imagine library
writer A suppressing one warning, and library writer B suppressing
another. Now I use library A and B, and now get two warnings suppressed
for my code, warnings that I wanted to see. This kind of effect makes
me think that, to be of any use, a #pragma-like ability would have to be
lexically scoped (“this file has these pragmas”). But that just seems
ugly. Imagine every file in some library having this block of pragmas
at the top. Every file. So that doesn’t seem like a win.

I think the best approach is to not rely upon “-w” at all, but use a
lint-like tool. I think there are some of these out there for Ruby.
You pick the lint you like, you configure its warnings to your liking,
and you run it. Since lint-like tools are not semantically scoped, but
file-scoped, you don’t have to worry about your lint tool bothering you
with warnings about some library that your program is using. You can
put it in your gem’s rakefile, or in a git commit hook. This, I think,
is the winning approach. Do not burden each Ruby implementation with
knowledge of policies and opinions which are (1) not universal, and (2)
subject to change as personal and community standards evolve over time.
Instead, decentralize warnings, putting them in separate tools.

  • Wayne C.

On Jun 25, 2014, at 4:44, Wayne C. [email protected] wrote:

2.1.1 :004?> end
(irb):3: warning: private attribute?

There is occasionally a valid reason to make a private accessor/reader/writer,
and no harm that I know of.

Not true. You can’t call a private writer (without send) because private
means you can’t use a receiver.

On Jun 25, 2014, at 5:46, Steve T. [email protected] wrote:

If you definitely want a private accessor/reader/writer, you can tell ruby like
this:

class Foo
attr_accessor :bar
private :bar
end

… and that is warning clean.

because that’s only the reader.

On Wed, Jun 25, 2014 at 10:21 PM, Ryan D. [email protected]
wrote:

… and that is warning clean.

because that’s only the reader.

True!

But this also runs without warnings:

class Foo
attr_accessor :x

private :x, :x=
end

It’s a good point that a private writer is useless, but I think Ruby is
doing the check for private when you create the attr 1.

On 06/25/2014 02:20 PM, Ryan D. wrote:

On Jun 25, 2014, at 4:44, Wayne C. [email protected] wrote:

There is occasionally a valid reason to make a private accessor/reader/writer,
and no harm that I know of.
Not true. You can’t call a private writer (without send) because private means
you can’t use a receiver.

Excellent point! I don’t know what I was smoking. I just checked, and
no warning is issued for a private attr_reader.

Wayne C.

Ryan D. wrote in post #1150753:

On Jun 25, 2014, at 4:44, Wayne C. [email protected] wrote:

2.1.1 :004?> end
(irb):3: warning: private attribute?

There is occasionally a valid reason to make a private accessor/reader/writer,
and no harm that I know of.

Not true. You can’t call a private writer (without send) because private
means you can’t use a receiver.

class Dog
attr_reader :x

def x=(str)
@x = str.capitalize
end

private :x=

def do_stuff
self.x = ‘hello’
end
end

d = Dog.new
d.do_stuff
puts d.x
d.x = “Goodbye”

–output:–
Hello
1.rb:18:in <main>': private method x=’ called for
#<Dog:0x00000100909740 @x=“Hello”> (NoMethodError)

On Wed, Jun 25, 2014, Ryan D. wrote:

2.1.1 :001 > class Foo
2.1.1 :002?> private
2.1.1 :003?> attr_accessor :bar
2.1.1 :004?> end
(irb):3: warning: private attribute?

There is occasionally a valid reason to make a private accessor/reader/writer,
and no harm that I know of.

Not true. You can’t call a private writer (without send) because private means
you can’t use a receiver.

Hmm; that doesn’t seem to be the case at least in 2.1.1:

class Foo
  private
  attr_accessor :bar

  public
  def set_bar(b)
    self.bar = b
  end

  def get_bar
    bar
  end
end

f = Foo.new
f.set_bar(42) # no warning except under -w
puts f.get_bar # outputs 42

Perhaps I misunderstand you, and you meant that using self as a receiver
for a private method merely triggers a warning under -w.

On Thu, Jun 26, 2014 at 7:14 AM, Eric C.
[email protected] wrote:

f = Foo.new
f.set_bar(42) # no warning except under -w
puts f.get_bar # outputs 42

Perhaps I misunderstand you, and you meant that using self as a receiver
for a private method merely triggers a warning under -w.

Oh that’s interesting, I would expect you to get a NoMethodError for
self.bar = b - I’ve created a gist1 based on this2 post by Jamis
Buck, that shows what I thought should happen. For some reason method
visibility seems different with the = operator.

On Thu, Jun 26, 2014 at 10:04 AM, Steve T. [email protected]
wrote:

  private
end

self.bar = b
Why would you? bar= is defined.

Btw. 1.9.3 also did not choke with this.

Kind regards

robert