Sharp knives and glue

On 5/5/06, Kirk H. [email protected] wrote:

Better to change languages than to change Ruby.
transfer, and transformation.
How big is your team? Do you use any XP methodologies, or would you give
us an idea of what methodologies you do use? How big are the programs
you have written?

Les

Pat M. wrote:

instances, I think it’s more than reasonable to protect your code.
Right. And in those cases it may make sense to use a different
language. Various degrees of security often come with corresponding
development costs. For me, those day-to-day costs aren’t justified for
what I write; the pros and cons of Ruby work out quite well. But,
just as one might prefer C to Ruby when speed is the main concern, a
different language might be called for to satisfy other needs.

Better to change languages than to change Ruby.


James B.

http://www.ruby-doc.org - Ruby Help & Documentation
Ruby Code & Style - The Journal By & For Rubyists
http://www.30secondrule.com - Building Better Tools

Hi All,

I don’t really want to get into this discussion too much. I’m too new
to
really contribute and this thread is probably a bit confrontational for
me,
I just have a question that I would like some clarification on if
possible.

When using ruby on Windoze the RMagick gem can cause a lot of trouble.
Apparently it redefines some things in the String class. The long and
short
of it is that many ppl find it difficult/impossible to use the
file_column
plugin with Rails under windoze.

My question is, list/David, is this the situation that David is talking
about?

Thanx for any clarification.

Cheers

Dan

Dan,

Yes, this is an instance of the issues I was discussing.

I think James B. framed the issue perfectly in that it’s a trade-off
between (and I’m paraphrasing) freedom and security/costs.

James and others on the list are of the opinion that freedom in the high
order bit. For where Ruby is today, I think James has the right balance
and
that freedom should be the high order bit as folks come up with the next
set
of cool tools like ActiveRecord/Rails, etc.

I am taking the position that as Ruby-based systems become more complex,
the
balance changes. The Glue/RMagick/Instiki load issues are hints of the
issues that, I argue, will become more common as there are more
libraries
and more complexity in the Ruby/Rails/whatevers-next code bases.

One post drew the analogy to the danger of meta-programming and the
danger
of C/C++ pointers. I think it’s a perfect analogy. Pointers are
amazingly
powerful, when used correctly. Unfortunately, they were sometime
mis-used
which led to nasty program failures and they were ultimately bannished
from
the successor languages to C/C++ (Java, C#).

I think meta-programming should stay part of Ruby. I also think that
Ruby
should evolve (either through libraries or the runtime with switches,
etc)
to guard rails around meta-programming so that it’s power can be used
correctly.

Thanks,

David

PS – To avoid being branded a troll, this will be my last post in this
thread. I’m happy to discuss this issue privately.
PPS – I appologize to folks if they think I wasn’t listening to their
point
of view. If you think I’ve wronged you, please send me a note.
PPPS – For those who think I don’t know anything about
meta-programming,
please review the presentation I gave on meta-programming at the Silicon
Valley Ruby Conference (
http://dppruby.com/dppsrubyplayground/files/Preso.ppt) and check out a
Domain Specific Language I wrote using Ruby (
http://rubyforge.org/projects/sitemap)
PPPPS – For those who question my programming skills, if you’re using
OS X,
open Mesa and look at the credits. I wrote Mesa among other award
winning,
highly stable commercial applications.

David P. wrote:

powerful, when used correctly. Unfortunately, they were sometime
correctly.

Thanks,

David

PS – To avoid being branded a troll, this will be my last post in this
thread. I’m happy to discuss this issue privately.
I think this is exactly the right place to discuss this issue!!

  1. I haven’t used meta-programming in a long time. The last time I did
    anything like it on a for-profit project was in the mid-1960s, and I had
    my head handed to me by management for it. It’s just not maintainable by
    anyone except the original programmer and those very closely
    associated with the original programmer.

In fact, I think the same goes for domain-specific languages. On a
software project, we already share a spoken language, one or more
programming languages, a shell/command line language, a revision/version
control system and lots of other environmental languages.

  1. Complex adaptive systems, no matter whether they are organizations,
    software, a living animal, or some combination of these, are … well
    … complex and adaptive. :slight_smile: Unmastered complexity is a project-killer.

I’m optimistic that Ruby (and Rails) will evolve as they take on larger
and more complex projects. Fortran has, Lisp has, Algol/C/C++/Java/C#
has, Perl has, PHP has and Python has. As I noted before, only one
language seems to have thought all of this out from the start, Ada.

P.S.: In case you haven’t noticed, I’m pretty much in violent agreement
with you, David.

P.P.S.: Yes, both meta-programming and domain-specific languages, called
by those names, were around in the mid-1960s. They didn’t start with
Ruby or Forth or even Lisp. Regular expressions and text editors made
them more or less unneccesary, at the cost of millions of lines of badly
factored code. :slight_smile:


M. Edward (Ed) Borasky

On May 5, 2006, at 8:27 AM, David P. wrote:

PS – To avoid being branded a troll, this will be my last post in
this
thread. I’m happy to discuss this issue privately.

I apologize if you feel I was “trolling” you. I didn’t mean to come
across so harshly.

James Edward G. II

Having skimmed over the thread, I get a taste of
‘Open classes bad. Strong typing good.’ Apologies if I’m paraphrasing
excessively,
but there’s no law saying I have to pay attention :slight_smile:

On 05/05/06, M. Edward (Ed) Borasky [email protected] wrote:

  1. I haven’t used meta-programming in a long time. The last time I did
    anything like it on a for-profit project was in the mid-1960s, and I had
    my head handed to me by management for it. It’s just not maintainable by
    anyone except the original programmer and those very closely
    associated with the original programmer.

That assumes the language makes it difficult to do cleanly, and I
honestly
don’t think that’s true in Rubys case.

I’m not saying it’s always safe. If you’re advocating a ‘best practice’
approach
then I’m all for it.

Can I propose “extend the object, not the class” as rule #1.

In fact, I think the same goes for domain-specific languages. On a
software project, we already share a spoken language, one or more
programming languages, a shell/command line language, a revision/version
control system and lots of other environmental languages.

Yes, but C doesn’t have key

  1. Complex adaptive systems, no matter whether they are organizations,
    software, a living animal, or some combination of these, are … well
    … complex and adaptive. :slight_smile: Unmastered complexity is a project-killer.

The last two statements seem in opposition.

Cheers

On 05/05/06, Dick D. [email protected] wrote:

Can I propose “extend the object, not the class” as rule #1.

In case that’s a bit opaque, this page explains what I’m on about:

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

  • especially the phrase

‘You could add the POP3 server methods to class TCPSocket but that
pollutes a general-purpose system class that you might be using for
other things.’

On Friday 05 May 2006 1:33 am, Leslie V. wrote:

How big is your team? Do you use any XP methodologies, or would you give
us an idea of what methodologies you do use? How big are the programs
you have written?

Two people, currently, who are geographically separated.

Regarding code size, it varies. A lot can be done in a small linecount,
when
one doesn’t consider the size of frameworks or libraries being used.

The largest single system is 20kloc. It’s a system for a real estate
appraisal company to manage their appriasal ordering/assignment/tracking
process paperlessly (and to be honest, if I wrote it today, I’m sure
that LOC
would be under 10k).

There are a number of systems in the 5-10kloc neighborhood that are used
for a
lot of different data tracking/handling tasks in various companies. And
then
there are a bunch of small systems, many less than 2kloc (some much
less),
used for very targetted purposes.

As for methodologies, it really boils down to some very basic things.
There
is no pair programming or anything of that nature. The basic process
tends
to move from a general idea about what the company wants through to a
set of
business requirements over the course of a lot of talking with the
customer.
Sometimes they have specific requirements already fleshed out, but in
practice, the process is one that entails a lot of questioning and
discovery,
as the requirements are often, frankly, very poor. After that, the
process
becomes one of release early, release often, as it is being developed.

Because that questioning and discovery phase is so common and is tied so
intimately with nebulous requirements, it goes on contantly while the
product
is being developed, and sometimes that means that halfway through the
project
it is discovered that the customer had a requirement in their heads that
was
poorly communicated or simply assumed on their part, but they don’t
realize
it concoulsly until they see the project coming together. It can be a
pain,
but when it happens, it happens, and we just deal with it.

Throughout the development process there is a lot of testing, both from
automated tests and the human-driven variety. That makes it easier to
shift
gears midstream when an unexpected requirement rears its head. It also
helps
ensure that when the system is finally delivered in a completed form to
the
customer, that it fullfills their business requirements, and it makes it
easier to write documentation for them.

Like I said, there isn’t a lot of really sophisticated methodology.
It’s all
pretty basic. Get the best requirements one can, usually through alot
of
discussion and questioning. Stay agile in devopment because
requirements
will mutate. Keep asking questions. Don’t over-engineer; it tends to
interfere with the requirement to stay agile, even when it seems like a
good
idea at first. :slight_smile: And test test test.

That’s basically it.

Kirk H.

No no no. Don’t do that. I don’t think anybody accused you of
trolling except for me, and I regret that. I think I was just in a
bad mood for reasons that aren’t relevant to the topic. Your points
are valid and interesting and belong here.

  • Jake

As I have matured, I’ve become more and more convinced how much louder
actions speak than words. This is most especially true in the world of
open source software.

In the current case, I would suggest that if David is so convinced of
a need for locking down core classes or limiting meta-programming in
Ruby at the Enterprise level, then he should provide some possible
solutions for that in code. I do agree that modification of core
classes and meta-programming can be a source of problems, just like
any powerful language feature. It probably would be nice to be able to
have control over that at the language level.

But I’ll be even more convinced if someone showed me some code that
accomplished this and was easy to use instead of telling me it needs
to be done.

I think much of the push-back David experienced in this thread was the
tone of “this really needs to be done”, without any offer of actually
taking part in the doing. You just can’t tell people what to do on an
open source project. We all get that enough at work, thank you.

I would suggest that David’s posts would have much more warmly
received if they were more like this: “Hi guys, I too have seen the
kind of problems talked about in this thread, and I came up with this
little solution for it. Take a look and let me know what you think.”
Instead it seems we got: “Yo guys, Ruby is just not ready for the
enterprise, because of X and Y and Z. You guys really need to get on
the ball if you ever expect Ruby to be anything important!”

Ryan

Brian Moelk wrote:

I’m a Ruby newbie, but having done a bunch of work in other languages, I do
think you have a point.

OTOH, I think you’re exaggerating the extent of the problem. As others have
mentioned, various testing practices can mitigate the legitimate issues that
you put forth. It’s also worth stating, again, that these kinds of problems
aren’t exclusively Ruby’s.

“Testing can only show the presence of bugs, not their absence.” E.W.
Dijkstra

FWIW, I too don’t feel comfortable with changing lower level classes that
alter “default” behavior, so it would be nice to at least have some easy way
of detecting if this has occured for the “core” Ruby classes. Maybe a
RubyLint? I see there is CheckR on RubyForge, but it looks to be in the
very early stages.

I don’t feel comfortable in modifying the language at all! I gave up on
Squeak because

  1. The user interface was so totally orthogonal to everything I’ve ever
    touched that I didn’t see the point in learning it, and

  2. It’s possible to modify the language, the operating system, the
    libraries, everything.


M. Edward (Ed) Borasky

Cool, this sounds like a plan David. This was exactly what I wanted my
email to achieve. While we Ruby programmer’s love the power and
flexibility of re-opening classes, there are probably times when we
all want to lock things down. Having the option of doing this
shouldn’t hurt anything, in my opinion.

FYI, I’m not sure if what you propose is possible in pure Ruby (at
least easily), so if you can hack C you might have to look into making
a C extension or a patch to the interpreter. Hopefully it won’t be so
bad though.

Regards,
Ryan

Ryan L. wrote:

Cool, this sounds like a plan David. This was exactly what I wanted my
email to achieve. While we Ruby programmer’s love the power and
flexibility of re-opening classes, there are probably times when we
all want to lock things down. Having the option of doing this
shouldn’t hurt anything, in my opinion.

FYI, I’m not sure if what you propose is possible in pure Ruby (at
least easily), so if you can hack C you might have to look into making
a C extension or a patch to the interpreter. Hopefully it won’t be so
bad though.

$ cat freeze-core.rb
@classes = {}
def do_freeze(klass)
klass.freeze
@classes[klass] = true
end
ObjectSpace.each_object do |o|
do_freeze(o) if o.is_a?(Class) and !@classes.has_key?(o)
end

$ ruby -r freeze-core -e ‘puts “foo”’
foo
$ ruby -r rubygems -r freeze-core -e ‘puts “foo”’
foo
$ ruby -r freeze-core -e ‘class String; def len; “foo”; end; end’
-e:1: can’t modify frozen class (TypeError)

Something like that?

It also struck me that the require mechanism could be hijacked to
enforce per-file namespacing to give something like Python’s system,
which seems to work fairly well. A require_ns() that wraps a module
named after the filename around the code it includes… Would that
help?


Alex

Ryan,

So… “Put your code where your mouth is?”… and given that my mouth is
big, my code should be good (my comments about me, and not ascribed to
you)… :slight_smile:

I think you’re absolutely right!

I’ll work on some ‘lock-down’ code that will allow classes to lock
themselves down from external modification (not Foo.freeze, but
something
more granular.)

I’ll toss it out to the group and see what people have to say.

Thanks,

David

Would this still allow extensions to an instance? This should still be
allowed yes?

@obj.extend(something)

$ ruby -r freeze-core -e ‘puts “foo”’
which seems to work fairly well. A require_ns() that wraps a module
named after the filename around the code it includes… Would that help?

Here are my ideas (bearing in mind that I am not much of a Ruby
programmer):

I don’t want any of my classes frozen. Say I want all string objects
passed to my function to be able to represent themselves in a certain
way…
ie. my function needs strings in culy braces. So the natural thing for
me would be this:

class String
def curlify
“{”+self+"}"
end
end

This is where I need the curlies and it makes sense for them to be
there.

I even want to be able to say:
require “curlystrings”

And have my strings be able to be curly.

What might be better, though is something like this:

irb> require “curlystrings”
unsafe require, “curlystrings.rb” attempts to add new definition
“curlyify” to existing class “String” in line 5 of
“/home/lesliev/curlystrings.rb”. You may want to use
require_over_existing.

irb>
irb> require_over_existing “curlystrings”
=> true

That’s the one thing - if I require something, it can’t modify
pre-existing classes without me authorizing that.

The other thing is that a gem or library should not be loaded unless I
“require” it. This was the Glue problem. So unless I say “require”,
what is not listed in the “built in classes and modules” part of the
Ruby manual should not be part of my environment.

Is this all reasonable?

On Sat, May 06, 2006 at 06:20:54PM +0900, Alex Y. wrote:

$ ruby -r freeze-core -e ‘class String; def len; “foo”; end; end’
-e:1: can’t modify frozen class (TypeError)

I’ll work on some ‘lock-down’ code that will allow classes to lock
themselves down from external modification (not Foo.freeze, but
something more granular.)
=======================

It also struck me that the require mechanism could be hijacked to
enforce per-file namespacing to give something like Python’s system,
which seems to work fairly well. A require_ns() that wraps a module
named after the filename around the code it includes… Would that help?

Several implementations have been proposed on ruby-talk before; they
failed
in cases like

$ cat bad.rb
::String.class_eval do

forces top-level, defies our efforts to wrap it

def size; 0 end
end
$ cat naive.rb

a = “foo”
p a.size
load(“bad.rb”, true)
p a.size
p $"

$ ruby naive.rb
3
./bad.rb:3: warning: method redefined; discarding old size
0
[]

See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/27417 for
another proposal.

On 06/05/06, Leslie V. [email protected] wrote:

ie. my function needs strings in culy braces. So the natural thing for
me would be this:

class String
def curlify
“{”+self+“}”
end
end

This is where I need the curlies and it makes sense for them to be there.

But then you’ve tampered with the very fabric of reality (HPL would be
proud) [1].

You could just modify the object you were passed:

def func_that_needs_strings_to_have_a_curlify_method(str)
def str.curlify
“{” + self + “}”
end

do something with str

end

This has the side effect on permanently adding a curlify method to
whatever
str points at, but not all Strings in the universe.

You might not want that, of course - but it has less impact than
modifying all strings. (If you only wanted that method to apply with
your
function, you could dup the object you were passed before meddling
with it.

Obviously this example is a bit contrived, but if you were redefining
something like the length() method, it would be saner to limit the
effect
of that.

[1] The ability to meddle with the fabric of reality is a feature, not
a bug, IMO. One of my fondest programming memories is the funny looks I
got
when I discovered I could redefine Integers ‘+’ method to always return
2.
I don’t cackle often :slight_smile:

On 5/6/06, Dick D. [email protected] wrote:

end
with it.
Yes… and if I have 50 functions that need curlify? How would I add
curlify to all strings that are passed to methods in my module, for
example?