Austin Ziegler wrote:
I don’t actually see this (that everything is “almost” an object).
Personally, I think that matz has made the right choice in making
boolean operations (and, &&, or, ||) invariant in the language. You
can, by the way, redefine the bit operators (& and |). There’s
nothing worse than a language which doesn’t do what you expect it to
do with conditionals, and it does so on the whim of another
programmer.
Ok, you are right, it’s Mr. Matz decission, but, why then can I redefine
the “and” method ? It must be a method in the very first time, not an
exception.
Why is not “=” a method?
Because it’s not something done to objects, but to reference
variables that we use to manipulate objects. I’m really curious as
to why one would want to redefine assignment in the first place. I
mean, seriously. It’s not like this is C++ where you have to
reinvent everything every time you work with the bloody language.
It’s not a question to redefine the “=” operator it’s a question of
orthogonality, what you learn for one thing is equally applicable to
other parts of the language, it’s interesting some times to have the
option to redefine the equal operator, but in most of the cases doing so
is adding a real complexity to the understanding of the program, this
does not means, that if you need to do it you can
Same question for “and” and the rest of operators that can not be
redefined, Does the actual implementation make life easier for the
designer ? I say so because for me is more natural when everything
is an object (without exceptions, here Ruby follows the rule
pretty well) and a method is a method ever, not sometimes.
This is just MNSHO, but again I don’t see why one would want to
allow such basic constructs to be redefined. IMO, you can redefine
everything except boolean tests and still have a useful – if obtuse
– language; if you try to redefine those, you’re not going to be
able to have any determinacy with the programs that are written.
You can…
class TrueClass
def and (anArgument)
return “hello”
end
end
I’ve redefined the and, it does not work, but it does not generate any
warning or error…
Why is it necessary to access the primitives? IMO, Java’s biggest
problem is that it makes the primitives available. In Ruby, by the
way, I can still change the behaviour of String – this is where
Ruby differs from every other language that I’ve ever used: it’s
dynamic. If I need a new function on String, I can add it whenever I
need. I’m looking at extending the functionality of a library that
I’ve ported so that it can optionally extend String and Array to
include this library as methods on String and Array instead of as
something else to operate on a String or an Array.
Yes it’s not needed, in Basic, you can not access the primitives and the
language is still working, but Ruby is much more powerful and flexible,
not because you can access the primitives, but because the language
gives you more options. The primitive access is just another option.
Consider for example the string extension you want
class String
def strExtension
call libStrgExtension.o:110
end
end
It’s not this way much more easy to do?
Yes you can have the “required” clause and use binary libraries,
but would not be much more “natural” to have a “require string”
when you want to invoque string libraries instead of having them
loaded all the time ?. I want to say here that the “primitive”
keyword frees the language from it’s implementation. This favours
the everything is a module aproach.
I disagree – allowing access to the primitives ties the developer
very tightly to the local implemententation of the language. I don’t
particularly care whether or not my integers are 32-bit or 64-bit or
even larger – I just expect them to do what they should do (and
that means possibly upclassing to a BigNum class if I exceed the
word size). I think that the only thing that I’d like to see in this
regard is for Ruby to take a page from Ada and allow me to define
ranges as types (that is, I want to be able to automatically define
a class UInt64 < Integer [(-264) … (264 - 1)] and have it do
the Right Thing).
Ok, you have a good point here. Ruby now deals with primitives, and you
don’t care if the Integer is 32 or 64 bits, it’s just an integer, you
can care of their limits only. Any development using explicit
primitives are not going to change this
class Integer # In a 32 bit environment
def sqrt
call libRubyMath.o:110
end
end
class Integer # In a 64 bit environment
def sqrt
call libRubyMath.o:110
end
end
Oh!!! it’s the same !!!, Why there is no diference ? because Ruby is
tied to the environment where it is working, as happens now, you invoque
ruby from the command line and you don’t care if the system is 32 or 64
bits, you make now primitive calls implicitly, as much as you don’t care
if the system is Linux or Windows (ok, without using plattform extensions)
It would NOT be much more natural to require every bloody module I
need every time I need it. A language – especially a language like
Ruby, where Strings are fundamental to everything – isn’t useful
without certain defaults. Would it not make equal sense to “require
integer” when I need to use integers, or are you suggesting that
those are fundamentals and are always included? Strings are part of
what makes Ruby useful immediately (the same applies to Files)
because it’s a scrpiting language.
I did put “String” as an example, but in fact the only needed module is
“kernel”, the base of the language, where Object, Boolean, and Magnitude
are defned (in Ruby there is no Boolean class and no Magnitude, but you
have Fixnum and TrueClass and FalseClass, I think that this is going to
change in the future). The rest are extensions, what an OO language is
supposed to deal with.
I’m sorry, but I don’t understand what you’re getting at here. The
three examples you gave:
a.+(3)
a.+ 3
a + 3
are actually the only ways to express that thought (without getting
silly wrt parenthesis). Ruby explicitly makes parentheses optional
on method calls. Parentheses make complex operations easier to read,
certainly, and can prevent confusion for the interpreter and
programmer, as when you have:
a b, c d
// Is this a(b, c(d)) – OR
// a(b), c(d)
This means only that “a + 3” is syntactic sugar for “a.+(3)” because
it is fundamentally more natural for most people to write “a + 3”
than either “a.+(3)” or even RPN “a 3 +”. Again, matz has made the
proper choice – it keeps the language easily accessible.
You will like then the Perl’s “there is a hundred ways to do it”
slogan… 
The fact that there is more than one way to express something, weakens
the mastery of the language. It’s right sometimes becasue it makes
things so “eye sugar” , but I prefer ( I PREFER, it’s me, my option) a
one way to do things, it makes things easy to code and easy to read your
own code and the one made by others.
Actually, it can’t give you the same results without trouble. C++
is trouble because it allows the definition of:
a = a + b // a.=(a.+(b))
to be different from:
a += b // a.+=(b)
If the result of the first call isn’t the same as the result of the
second call, then there’s a disconnect which has to be documented.
Matz made the right choice here, I think, because it prevents this
sort of stupidity that C++ allows. (And this isn’t ‘prevention’ in
the way that I think GvR was beyond silly to require indentation for
block definition in Python.)
I disagree, You loose flexibility, it does not mean that you need to use
it, it means that you have the flexibility there when you need it.
Anyways, if I define a.+=b to be diferent from a.=a.+b it’s my own fault
for using bad semantincs, but it can be posible that someone must be
interested in having side efects associated with the += operator (as in
C++, and yes it’s troublesome). In Smalltalk you can do it and there are
no problems with the added flexibility, contrary to C++ where a lot of
programmers started to do OOP without a solid background on OO analisys,
this bring us the problems with C++
The interpreter will warn you of this, to some degree. If I try to
use an undefined variable, it will complain (at least with 1.7)
because the value is unknown (it’s not even properly ‘nil’). This
won’t help, however, if you have two similarly named variables.
OK, I’ll try…I’m using Linux with 1.6. Anyways a warning would be a
great addition, you will catch the error at compile time instead of at
run-time.
This one is easy: because it was a design decision made earlier. A
new version of String is being worked on, to the best of my
knowledge, that will deal with characters – but this leaves the
problem of existing code which will break because it uses the
current implementation.
It does not need to break nothing a character is an integer with a dual
personality, maybe you will just need to redefine some methods based on
the arguments, but I don’t foresee serious problems.
A bytecode system is being worked on, to the best of my knowledge.
Someone pointed me to Parrot, I’ve done him just a look, and it’s
interesting.
Enric