Ideas on "Why Living Dangerous can be A Good Thing" in Ruby?

G

Gregory Brown

I'm not saying there aren't valid concerns. What I'm saying
is: can those concerns be elaborated beyond some general
notion of 'fear' or 'security' and wouldn't that help construct
a more appropriate response?

The fear in part has to do with type checking. Ruby being typeless
scares people who tend to believe that type checking is absolutely
essential to 'safe' programming. But as David Black and many others
had mentioned, safety is in the hands of the programmer.

I personally have never crashed my computer using Ruby. On the
gripping hand, I've done many unsavory things in C, and at least a
couple in Perl. These were 'accidents'.

I think that it's worthwhile to point that since low-level management
is not something we need to do in Ruby, such accidents are far less
likely to happen. I think that this type of thing makes up the
lionshare of bugs and vulnerabilities. You hear about overflow
exploits on a day to day basis... you very rarely hear of the l33t
h4x0r using metaprogramming to destroy a system.

People are afraid that without the type checking safety net, that the
program will begin to act unpredictable or will be capable of doing
random unsavory things.

The bottom line is, if you're in a production environment, you should
have all of your projects running against a comprehensive test suite.=20
Continuous integration should be assumed. Though it's universally
agreeable that regardless of the language you choose, you 'should' be
doing this, I do believe the popular opinion in most of the
experienced ruby core community is that you *MUST* be doing this.

And you know what? It takes me about 30 seconds to find out what
jimmy's evil little gem has done to my system when I run my units on
all my projects to make sure they haven't broken with the addition of
a new library.

I mean, come on, does anyone add a require 'foo' from the wild into
production code WITHOUT running their units? If they do, well then
all bets are off.

The biggest thing that those with a fear of dynamicity need to
recognize is that it's not as if we're programming in Java or C++ but
just removing the type checking and other 'security' measures. We're
programming in a language that was designed from the ground up to be
used in the way we're using it.

Reflection and introspection in Ruby are so good we can actually use
it to PREVENT unsavory effects through using it in our unit tests.=20
Things like method_missing and respond_to? and the ability to search
our entire object space are features, not bugs.

This type of design allows for things like inversion of control /
dependency injection, which can be used to cleanly tack on logging and
unit testing features WITHOUT having to pollute methods with secondary
code.

I think that things like automated memoization make me LESS likely to
screw up than it would to roll my own in every single method that
needs it.

Ruby is no different than any other language. Bad code and bad coders
will cause problems, good code and good coders will solve problems.=20
Simply because it was not a design goal to make the programmer feel
safe and 'secure', but rather to make them feel powerful is NOT a
flaw.

Wow... i'm ranting here. Better here than in my article I suppose,
but there are my answers to our still yet to be precisely defined
questions ;)

Let me know what you think.
-Greg
 
G

gwtmp01

If you remember from our first New Haven Rubyists meeting, there was a
decent amount of tension from the Java guys in the house. People who
tend to lean on the compiler for support feel like they're going to
fall flatfaced upon entering Ruby.

I remember. I'm just trying to understand the concern at a finer
level of detail. I feel like a therapist trying to coax a
reluctant patient to talk about their nightmares. :)


Gary Wright
 
G

Gregory Brown

I remember. I'm just trying to understand the concern at a finer
level of detail. I feel like a therapist trying to coax a
reluctant patient to talk about their nightmares. :)

I've asked my CS advisor to come up with her concerns in the form of
specific questions. If she does so, I'll post them here.
 
E

Eivind Eklund

Does a language with type-inference require as many type and variable
declarations as a language without type-inference?

Does a reference to declaring types and variables make it clear to you
that we're talking about a language where you have to declare types
and variables, and *not* one based on type inference?
Is the C++ type system the same as the SML type system?

Does the SML type system include declaring types and variables to the
degree of taking up roughly half the code?
Will programmers who passively suffer compiler type-checking detect as
many bugs as programmers who actively use 'type-full' programming as a
checking-tool?

Will people that use the annoying technique of asking bad rethorical
questions get on your nerves too?

;)

Really, and in all friendliness, the question isn't if they'll detect
as many bugs. The question is if those that tries to use types as a
checking tool find so many bugs and/or get so many other benefits that
the costs introduced by the types are worth it. The answer will vary
by language, by environment, by programmer, and by methodology used.=20
I believe the static type system of SML or Haskell may well be worth
it - I've just not worked enough with it to know.

For me, in the environment I work in, with the ways I work with Ruby,
I've found that very few of my bugs would be caught by extra type
checking. I just don't end up with wrongly typed data much at all,
and in the few cases where I do, the errors have come up immediately.=20
Since I wrote my type checking library, I've not had a subtle bug that
would be caught by more type checking. Before I wrote the type
checking library, I thought that adding more type checking would catch
a significant amount of bugs. When I added more type checking and
found that it got in the way, I started looking for cases where it
would have helped. I found very few, and they've so far shown up
immediately (as methods missing).

Eivind.
 
G

gwtmp01

I remember. I'm just trying to understand the concern at a finer
level of detail. I feel like a therapist trying to coax a
reluctant patient to talk about their nightmares. :)

Just to be clear. I'm not thinking of Greg as the patient. I'm talking
about the folks who are 'fearful' of Ruby and other similar language
environments.


Gary Wright
 
G

Gregory Brown

Ruby is not typeless.

Aren't all ruby objects under the hood of type VALUE?

sandal@karookachoo:~$ irb
irb(main):001:0> 3.type
(irb):1: warning: Object#type is deprecated; use Object#class
=3D> Fixnum

So... aren't we supposed to ignore type now? ;)

Please elaborate on what you meant by this, because I am interested.
( My conception of ruby's type system might have been wrong)
 
I

Isaac Gouy

Eivind said:
Does a reference to declaring types and variables make it clear to you
that we're talking about a language where you have to declare types
and variables, and *not* one based on type inference?
No


Does the SML type system include declaring types and variables to the
degree of taking up roughly half the code?

Depends how you write it
Will people that use the annoying technique of asking bad rethorical
questions get on your nerves too?

;)

Not as much as those who make wild generalizations ;-)
 
G

Gregory Brown

Just to be clear. I'm not thinking of Greg as the patient. I'm talking
about the folks who are 'fearful' of Ruby and other similar language
environments.

However, this does NOT neccessarily mean I am in no need of therapy ;)
 
D

dblack

Hi --

Aren't all ruby objects under the hood of type VALUE?

But Ruby != Ruby-under-the-hood :)
sandal@karookachoo:~$ irb
irb(main):001:0> 3.type
(irb):1: warning: Object#type is deprecated; use Object#class
=> Fixnum

So... aren't we supposed to ignore type now? ;)

The reason #type is deprecated is not that there's no such thing as
type, but that having a #type method that returns the object's class
leads people to think that type and class are the same. In fact, my
understanding is that the only reason Matz resorted to a #type method
was that there were problems getting the parser to treat "class" as a
method name, even with an explicit receiver.
Please elaborate on what you meant by this, because I am interested.
( My conception of ruby's type system might have been wrong)

The type of a Ruby object, as I understand it, is basically its
capabilities, at a given point during runtime. So objects have types
-- but the types themselves are anonymous and, in a sense, circular.
(The type of x is "the type that objects that do what x does have".)


David

--
David A. Black
(e-mail address removed)

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black
 
J

James Britt

Gregory said:
Aren't all ruby objects under the hood of type VALUE?

How far under the hood do we want to look?
sandal@karookachoo:~$ irb
irb(main):001:0> 3.type
(irb):1: warning: Object#type is deprecated; use Object#class
=> Fixnum

So... aren't we supposed to ignore type now? ;)

Please elaborate on what you meant by this, because I am interested.
( My conception of ruby's type system might have been wrong)

I'm going to punt and refer you to this:

http://www.rubygarden.org/ruby?TypesInRuby

which, hopefully, is both correct and reasonably complete.

The short answer is, Ruby objects have a type, which essentially is "the
type that responds to those methods I happen to respond to."

In /most/ cases, asking an object for its class is sufficient for
determining type, but that gets back to the real topic: Not all objects
of, say, class String are assured to respond to the same messages, and
to the extent that so-called String objects differ in their
message-acceptance, they are different types.



James
--

http://www.ruby-doc.org - Ruby Help & Documentation
http://www.artima.com/rubycs/ - The Journal By & For Rubyists
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools
 
P

Phrogz

However, to the outsider, this is only an explanation of "how" to
overcome the apparent "flaw". I'd like to do as good a job I can of
explaining why it isn't a flaw, when practiced correctly.

There seems to be some sort of logical fallacy at play here, but I
can't sniff out what it is. Arguing from authority? Begging the
question?

You seem to be half-asking for good answers to "Is Ruby's openness a
flaw?" and at the same time looking for good answers to the argument
"Why Ruby's openness isn't a flaw."

I would argue that it IS a flaw...for some people, use cases, or
programming styles. At the same time, I would then argue that it's also
a huge feature...for some people, use cases, or programming styles.

Don't try to convince people that they're wrong for wanting a compiler
to catch certain typos for them without writing use cases. Don't tell
them "if you include libraries A and B in your application, and B
modifies A in a way that neither's documentation covers...that's a
feature! You should embrace it, not hate it!"

Instead, convince them that use cases are more secure than the false
sense of security syntax- and static-checking provide. Acknowledge that
there ARE some downsides to the openness, but that they are outweighed
by the freedom provided.

This thread is not about a language war, but touches on issues at the
fringes of one. Remember that no one language is the Right language for
all cases. There may be cases where the openness of Ruby makes it the
wrong choice.

To convince people that Ruby is Right for cases where they are clinging
to a few misconceptions:

1) Identify clear problems, or perceived problems.
2) One by one, lay out:
2a) What the problem is in Ruby.
2b) Why it isn't (or is) a problem in the 'standard' language of
choice.
2c) How you can remove or mitigate the problem in Ruby using additional
features or changed coding styles. If you can't, say so.
2d) What benefits are made possible by the features of Ruby that cause
the problem.

The combination of 2c and 2d should give the listener a good idea of
cost/benefits. 2b may give the user an 'ah-ha' moment, realizing they
have misconceptions, or have been relying on a false sense of security.
 
G

Gregory Brown

But Ruby !=3D Ruby-under-the-hood :)

True. :)
The reason #type is deprecated is not that there's no such thing as
type, but that having a #type method that returns the object's class
leads people to think that type and class are the same. In fact, my
understanding is that the only reason Matz resorted to a #type method
was that there were problems getting the parser to treat "class" as a
method name, even with an explicit receiver.
interesting


The type of a Ruby object, as I understand it, is basically its
capabilities, at a given point during runtime. So objects have types
-- but the types themselves are anonymous and, in a sense, circular.
(The type of x is "the type that objects that do what x does have".)

Hence duck-typing, no? ;)
 
G

Gregory Brown

Instead, convince them that use cases are more secure than the false
sense of security syntax- and static-checking provide. Acknowledge that
there ARE some downsides to the openness, but that they are outweighed
by the freedom provided.

This thread is not about a language war, but touches on issues at the
fringes of one. Remember that no one language is the Right language for
all cases. There may be cases where the openness of Ruby makes it the
wrong choice.

This is what I'm trying to do:
http://rubygarden.org/ruby?TheOpenNatureOfRuby

I am not trying to prove that Ruby's openness is right for everything
and everyone, but rather show that it is right and does work for
*Ruby*.

This is something that a lot of people are critical of, and I'd like
to try to explain it without terribly too much bias.
 
G

Gregory Brown

I'm going to punt and refer you to this:

http://www.rubygarden.org/ruby?TypesInRuby

which, hopefully, is both correct and reasonably complete.

This page did explain what I was wondering, thanks.
The short answer is, Ruby objects have a type, which essentially is "the
type that responds to those methods I happen to respond to."

In /most/ cases, asking an object for its class is sufficient for
determining type, but that gets back to the real topic: Not all objects
of, say, class String are assured to respond to the same messages, and
to the extent that so-called String objects differ in their
message-acceptance, they are different types.

So would it be agreeable that comparing static typing to duck typing
is truly an apples to oranges comparison?

That a state driven environment simply cannot be easily compared to a
behavior driven environment?

And if that's the case, would we benefit most by explaining what
exactly a behavior driven system looks like and how to best use it to
meet your needs, while avoiding pitfalls?

Maybe this would avoid language wars and instead incourage people to
just think a little bit differently when they sit down to try out
ruby.
 
P

Paul Novak

Some of the anxiety that those from a statically-typed background
experience when coming to a dynamically-typed language stems from the
environment that they have been swimming in.

If you spend much of your time answering the compilers complaints
about type-related issues, and you find yourself writing reams of
boilerplate just to get similar types to perform essentially the same
behavior, you might come to believe that static typing must be
important.

Of course, once you dive in and truly immerse yourself in a dynamic
language you get comfortable with duck typing. You don't even give it
much thought until you have to explain to someone why it is not that
dangerous after all.

When the language is not getting in your way, you are free to focus on
your problem domain rather than worry about how to get the language
out your way.
 
S

Steve Litt

Some of the anxiety that those from a statically-typed background
experience when coming to a dynamically-typed language stems from the
environment that they have been swimming in.

Or for some of us it's just the opposite. I started on a Heathkit ET6800
Microprocessor Trainer with a 8 bit 6800 processor programmed in hexidecimal.
I spent a week trying to program it to play music using Gotos, which was what
many people still used in 1982. Then a programmer buddy told me about modular
programming (functionally decompose into subroutines), and I easily
programmed it. That gave me a love of encapsulation, and an absolute fear of
spaghetti programming, self modifying code, global variables, and the like.

When I got to C, I was grateful for type checking and local variables.

SteveT

Steve Litt
http://www.troubleshooters.com
(e-mail address removed)
 
B

Brian Takita

------=_Part_24356_23067941.1136932510619
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

If you like, you can use the method_added callback to see when a class gets
updated.

For example, putting the following code before your unit tests will give yo=
u
an indication of where methods are added. Of course it would probably be
best to require a file with this code.
Of course this doesn't cover everything (like methods being added via eval
or changing instance variables), but it seems with better analysis tools an=
d
libraries, this hole can be covered.
See
http://weblog.freeopinion.org/articles/2006/01/06/find-out-where-a-method-w=
as-added-in-rubyfor
more details.

# A class like this can be in a library somewhere. This is a rough
draft implementation.
class MethodDefinitionContainer
class << self
def instance
@instance =3D Hash.new unless defined? @instance
@instance
end

include Enumerable
def [](key)
key =3D key.to_sym
instance[key]
end

def []=3D(key, value)
key =3D key.to_sym
instance[key] =3D [] if instance[key].nil?
instance[key] << value
end

def each
instance.each do |key, value|
yield(key, value)
end
end
end
end

# End library code

class Object
def self.method_added(id)
MethodDefinitionContainer[self.to_s + '.' + id.to_s] =3D caller[0]
end
end

####
# Unit tests are run here
####

sorted_keys =3D MethodDefinitionContainer.instance.keys.sort

sorted_keys.each do |key|
puts key
values =3D MethodDefinitionContainer[key]
values.each do |value|
puts "\t" + value
end
end
 
J

James Britt

These links may be relevant to the general thread

Mob Software, by Richard P. Gabriel & Ron Goldman, and Programming
Bottom-Up, by Paul Graham

http://www.dreamsongs.com/MobSoftware.html
http://www.paulgraham.com/progbot.html

James

--

http://www.ruby-doc.org - Ruby Help & Documentation
http://www.artima.com/rubycs/ - The Journal By & For Rubyists
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top