Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > The real Ruby vs. Python.

Reply
Thread Tools

The real Ruby vs. Python.

 
 
vruz
Guest
Posts: n/a
 
      10-28-2004
First of all, this email is written by me, Horacio López and doesn't
necessarily reflect the opinions of the RPA team.

> We added it because we wanted the user to have the choice to remove a
> package even if it might screw something up. I see it as being in the
> same vein as allowing a programmer to pass a String into a method that may
> usually expect something else.


I see these comments in the same vein as comparing oranges to apples.

> "Here's some rope...you can use it to tie
> knots, secure things, etc. or you can hang yourself with it.


it could read more like:
"here's a nice tool, you can use it to run production installations
without breaking stuff, streamlining the process and behaving in a
predictable manner... or you can use your former package management
system of choice"

> We trust that you'll make the right decision, because we don't think you're an
> idiot."


it could read more like:
"we ease the job because our focus is quality, and not everyone is
willing or have time to spend building decent packages that work
together well"

We don't call people "idiots".

Some people believe just a little policy is good for production
environments, nobody is going to die because of it, and you can
happily continue to design another system that has another policy (if
any) that suits your needs better.

I would still like to know what's the Rubygems manifesto, set of
guidelines, what's the purpose, big idea, right now, based on your
comments and diverging opinions from other Rubygems developers,
features that appear and disappear in the next release, it's hard to
tell and it feels like a bit of a moving target.

It's way much more difficult to start a decent analysis of a system if
you don't know what it will be like in 10 seconds from now, perhaps
it's not even worth the hassle.

On the other hand, it's very easy to drop FUD about a clearly defined
roadmap, for bad or good.

best,
vruz



 
Reply With Quote
 
 
 
 
Guillaume Marcais
Guest
Posts: n/a
 
      10-28-2004
--=-XN87+79wxRM1KhQCmcRq
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Wed, 2004-10-27 at 17:53, Jamis Buck wrote:

> Besides which: Ruby/DL is often touted as a great way to write extension
> libraries. Are there any examples of libraries that have been written
> using Ruby/DL instead of C? I've never seen any, much to my own
> frustration when I would like a good example of Ruby/DL usage.


I wouldn't dare to brag about 'good example', but it at least is a
(mostly) working one. I say mostly as a good number of the settings for
a user are undocumented and I had to guess the return value type.
Anyway, the following code is a binding to the Merak mail server
library. It allowed may to automate the transition from our old mail
server to Merak. It is now a nice way to get the password in clear that
the stupid GUI shows as stars. The creation and basic settings of a
Domain and a User should work. The more exotic settings are untested.

Here is an example of a session using the created merak shell:

$ ssh Administrator@fakedomain irb -r merak_shell
Administrator@fakedomain's password:
Warning: Remote host denied X11 forwarding.
Merak 1:0> toto = Domain["toto.net"]
toto = Domain["toto.net"]
=> #<Domain name=toto.net; index=15>
Merak 2:0> user = toto["toto"]
user = toto["toto"]
=> #<User domain=toto.net index=0>
Merak 3:0> user.password
user.password
=> "coucou"
Merak 4:0> user.password = "hello"
user.password = "hello"
=> "hello"
Merak 5:0> user.save
user.save
=> #<User domain=toto.net index=0>

In short, I would never have written it if I had to drop down to C. One
reason being that I don't have a compiler installed on any Windows
machine yet.

Guillaume.


--=-XN87+79wxRM1KhQCmcRq
Content-Disposition: attachment; filename=merak.rb
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

require 'Win32API'

module Merak
class Error < ScriptError; end
class APIError < Error; end
class Failure < APIError; CODE =3D -1; end
class License < APIError; CODE =3D -2; end
class Params < APIError; CODE =3D -3; end
class Paths < APIError; CODE =3D -4; end
class Config < APIError; CODE =3D -5; end

ERRORS =3D [nil, Failure, License, Params, Paths, Config]

# Call function in the DLL. Return an error object if an error occures.
class APIClass
attr_reader :winapis
DLL =3D 'API.dll'
ARGS =3D {
:Init =3D> ["P"],=20
:GetDomainCount =3D> [],
:GetDomainList =3D> ["P", "L"],
:AddDomain =3D> ["P", "P", "L"],
eleteDomain =3D> ["L"],
:GetDomainIndex =3D> ["P"],
:GetDomainName =3D> ["L", "P", "L"],
:LoadDomain =3D> ["L", "P", "L"],
:SaveDomain =3D> ["L", "P", "L"],
:SetDomainDefaults =3D> ["P", "L"],
:GetDomainIP =3D> ["L", "P", "L"],
:SetDomainIP =3D> ["L", "P", "L"],
:GetDomainSetting =3D> ["P", "L", "L", "P", "L"],
:SetDomainSetting =3D> ["P", "L", "L", "P", "L"],
:GetUserCount =3D> ["P"],
:GetUserList =3D> ["P", "P", "L"],
:GetUserIndex =3D> ["P", "P"],
:AddUser =3D> ["P", "P", "L"],
eleteUser =3D> ["P", "L"],
:SetUserDefaults =3D> ["P", "L"],
:LoadUser =3D> ["P", "L", "P", "L"],
:SaveUser =3D> ["P", "L", "P", "L"],
:GetUserSetting =3D> ["P", "L", "L", "P", "L"],
:SetUserSetting =3D> ["P", "L", "L", "P", "L"],
}

def initialize; @winapis =3D {}; end

def method_missing(call, *args)
winapi =3D @winapis[call]
if winapi.nil?
api_args =3D ARGS[call]
raise Error, "Unknown API call '#{call}'" if api_args.nil?
winapi =3D @winapis[call] =3D Win32API.new(DLL, call.to_s, api_args=
, "L")
end
param =3D args.last.kind_of?(Hash) ? args.pop : nil
r =3D winapi.call(*args)
if r < 0
msg =3D "Error calling #{call}(#{args.join(", ")})"
pmsg =3D param ? param[("err_%d" % (-r)).intern] : nil
msg <<=3D "\n#{pmsg}" if pmsg
raise ERRORS[-r], msg
end
r
end
end # API
=20
# Different types to store in Merak fields
# Should implement pack, unpack, size and base_size
# The virtual type must be instanciate with a base_size argument
class BoolT
def self.pack(b); [b ? 1 : 0].pack("C"); end
def self.unpack(s); s.unpack("C")[0] !=3D 0; end
def self.size(s); 1; end
def self.base_size; 1; end
end
=20
class NumT
def self.pack(n); [n].pack("L"); end
def self.unpack(s); s.unpack("L")[0]; end
def self.size(s); 4; end
def self.base_size; 4; end
end
=20
class TimeT
def self.pack(n); nil; end
def self.unpack(s); nil; end
def self.size(s); 8; end
def self.base_size; 8; end
end
=20
class StringTVirtual
attr_accessor :base_size
def initialize(base_size); @base_size =3D base_size; end
def pack(s); s; end
def unpack(s); s; end
def size(s); s.size; end
end
=20
class ListTVirtual
attr_accessor :base_size
def initialize(base_size); @base_size =3D base_size; end
def pack(l); l.kind_of?(Array) ? l.join('; ') : l; end
def unpack(s); s.split(/[,;]/).collect { |x| x.strip }; end
def size(s); s.size; end
end

class TypeTVirtual
attr_reader :category
def initialize(category); @category =3D category; end
def pack(t); [@category.index(t)].pack("L"); end
def unpack(s); @category[s.unpack("L")[0]]; s.unpack("L")[0]; end
def size(s); 4; end
def base_size; 4; end
end

# Actual type of virtual definition
String32T =3D StringTVirtual.new(32)
String128T =3D StringTVirtual.new(12
String1024T =3D StringTVirtual.new(1024)
List128T =3D ListTVirtual.new(12
List1024T =3D ListTVirtual.new(1024)
=20
# Get/Set settings for object
module Settings
class << self
alias :__append_features :append_features
def append_features(mod)
__append_features(mod)
mod.const_get(:SETTINGS_DESC).each_key do |k|
mod.module_eval("def #{k}; get_setting(:#{k}); end")
mod.module_eval("def #{k}=3D(val); set_setting(:#{k}, val); end")
end
end
end

def get_setting(setting, b_size =3D nil)
s_desc =3D settings_desc[setting]
raise Error, "Unknown setting '#{setting}'" if s_desc.nil?
get_setting =3D settings_calls[:get_setting]
=20
args =3D [@buffer, @buffer.size, s_desc[:val], :buffer, :size]
r, buffer, args =3D call_retry(get_setting, s_desc[:type].base_size, =
args)
return s_desc[:type].unpack(buffer[0, r])
end
private :get_setting

def set_setting(setting, value)
s_desc =3D settings_desc[setting]
raise Error, "Unknown setting '#{setting}'" if s_desc.nil?
set_setting =3D settings_calls[:set_setting]

s_buf =3D s_desc[:type].pack(value)
r =3D API.send(set_setting, @buffer, @buffer.size, s_desc[:val],
s_buf, s_buf.size)
return value
end
private :set_setting
end # module Settings

module Utils
# Call an API methods, max attempts time, increasing the size of a buff=
er
# The buffer is located at :buffer.
# Return: [result, buffer, args]
def call_retry(call, size_base, args, attempts =3D 5)
b_index =3D args.index(:buffer)
s_index =3D args.index(:size)
return nil if b_index.nil?
=20
i =3D 1
begin
args[b_index] =3D buffer =3D " " * (i * size_base)
args[s_index] =3D buffer.size if s_index
r =3D API.__send__(call, *args)
rescue Params =3D> e
i +=3D 1
raise e if i > attempts
retry
end
=20
return [r, buffer, args]
end
module_function :call_retry
end

class Domain
include Utils

class << self
private :new
=20
def names
count =3D API.GetDomainCount
base =3D count * 50
r, buf, args =3D Utils.call_retry(:GetDomainList, base, [:buffer, :=
size])
buf[0, r].split("\0")
end

# Get by index or name
def get(ident)
case ident
when Integer
begin
r, name, a =3D Utils.call_retry(:GetDomainName, 50,=20
[ident, :buffer, :size])
name =3D name[0, r]
rescue Params
raise Error, "No such domain with index '#{ident}'"
end
index =3D ident
when String
index =3D API.GetDomainIndex(ident,=20
:err_1 =3D> "No such domain '#{ident}'=
")
name =3D ident
end
=20
res =3D new(index, nil, name)
res.reload
res
end=0D
alias :[] :get

def create(name)
r, buffer, args =3D Utils.call_retry(:SetDomainDefaults, 4192,=20
[:buffer, :size])
API.AddDomain(name, buffer, buffer.size)
index =3D API.GetDomainIndex(name)
new(index, buffer, name)
end

def delete(ident); get(ident).delete; end
end # class << Domain
=20
attr_reader :index
def initialize(index, buffer =3D nil, name =3D nil)
@index, @buffer, @name =3D index, buffer, name
end
=20
# Returns Virtual Binding IP, or nil if none
def ip
ip =3D " " * 16
r =3D API.GetDomainIP(@index, ip, ip.size)
return (r =3D=3D 0) ? nil : ip[0, r]
end

def ip=3D(ip)
ip ||=3D ""
API.SetDomainIP(@index, ip, ip.size,
:err_1 =3D> "Bad IP '#{ip}'")
ip
end

def save
return true unless @buffer
API.SaveDomain(@index, @buffer, @buffer.size)
self
end

def delete; API.DeleteDomain(@index); self; end

def name
return @name if @name
r, name, args =3D call_retry(:GetDomainName, 50, [@index, :buffer, :s=
ize])
@name =3D name[0, r]
@name
end

def inspect; "#<Domain name=3D#{name}; index=3D#{@index}>"; end

SETTINGS_DESC =3D {
:description =3D> { :val =3D> 0, :type =3D> String1024T },
:type =3D> { :val =3D> 1, :type =3D> NumT },
:domain_value =3D> { :val =3D> 3, :type =3D> String1024T },
ostmaster =3D> { :val =3D> 4, :type =3D> List1024T },
:admin_forward =3D> { :val =3D> 5, :type =3D> String1024T },
:unknown_users_forward =3D> { :val =3D> 6, :type =3D> BoolT },
:unknown_forward_to =3D> { :val =3D> 7, :type =3D> List1024T },
:info_to_admin =3D> { :val =3D> 8, :type =3D> BoolT },
}
def settings_desc; SETTINGS_DESC; end
private :settings_desc
SETTINGS_CALLS =3D {=20
:get_setting =3D> :GetDomainSetting, :set_setting =3D> :SetDomainSett=
ing=20
}
def settings_calls; SETTINGS_CALLS; end
private :settings_calls
include Settings
=20
def reload
args =3D [@index, :buffer, :size]
r, buffer, args =3D call_retry(:LoadDomain, 4192, args)
@buffer =3D buffer
r
end

# User management
def users
count =3D API.GetUserCount(@name)
base =3D count * 50
r, buf, args =3D call_retry(:GetUserList, base, [@name, :buffer, :siz=
e])
buf[0, r].split("\0")
end

def get_user(ident)
case ident
when Integer
index =3D ident
when String
index =3D API.GetUserIndex(@name, ident)
end

r, buf, args =3D call_retry(:LoadUser, 4192,=20
[@name, index, :buffer, :size])
User.new(self, index, buf)
end=0D
alias :[] :get_user

def create_user(*aliases)
r, buffer, args =3D Utils.call_retry(:SetUserDefaults, 4192,=20
[:buffer, :size])
u =3D User.new(self, nil, buffer)
u.alias =3D aliases unless aliases.empty?
u
end
alias :add_user :create_user
end # Domain

class User
include Utils
=0D
attr_reader :index, :buffer, :domain
def initialize(domain, index, buf)
@index, @buffer, @domain =3D index, buf, domain
end

def inspect
"#<User domain=3D#{@domain ? @domain.name : @domain_index} index=3D#{=
@index}>"
end

# class POP3; end
# class IMAP; end
# class IMAPandPOP3; end
# UserTypeT =3D TypeTVirtual.new([POP3, IMAP, IMAPandPOP3])
SETTINGS_DESC =3D {
:type =3D> { :val =3D> 0, :type =3D> NumT },
:anti_spam_index =3D> { :val =3D> 1, :type =3D> NumT },
:name =3D> { :val =3D> 2, :type =3D> String32T },
:alias =3D> { :val =3D> 3, :type =3D> List128T },
:mailbox =3D> { :val =3D> 16, :type =3D> String32T },
:account_disabled =3D> { :val =3D> 17, :type =3D> BoolT },
:account_valid =3D> { :val =3D> 18, :type =3D> BoolT },
:account_valid_till =3D> { :val =3D> 19, :type =3D> TimeT },
:check_virus =3D> { :val =3D> 20, :type =3D> BoolT },
:allow_remote =3D> { :val =3D> 21, :type =3D> BoolT },
:validity_report =3D> { :val =3D> 22, :type =3D> BoolT },
:validity_report_days =3D> { :val =3D> 23, :type =3D> NumT },
:nt_Password =3D> { :val =3D> 24, :type =3D> BoolT },
:imap =3D> { :val =3D> 25, :type =3D> BoolT },
:imap_mailbox =3D> { :val =3D> 26, :type =3D> String32T },
:max_message_size =3D> { :val =3D> 27, :type =3D> NumT },
:dont_show_messages =3D> { :val =3D> 28, :type =3D> BoolT },
:any_password =3D> { :val =3D> 29, :type =3D> BoolT },
:etrn =3D> { :val =3D> 30, :type =3D> BoolT },
:delete_expire =3D> { :val =3D> 31, :type =3D> BoolT },
:null =3D> { :val =3D> 32, :type =3D> BoolT },
assword =3D> { :val =3D> 33, :type =3D> String32T },
:nt_password_value =3D> { :val =3D> 34, :type =3D> String32T },
:domain_admin_index =3D> { :val =3D> 35, :type =3D> NumT },
:domain_admin =3D> { :val =3D> 36, :type =3D> BoolT },
:mail_box_path =3D> { :val =3D> 37, :type =3D> String128T },
:admin =3D> { :val =3D> 38, :type =3D> BoolT },
:max_box =3D> { :val =3D> 39, :type =3D> NumT },
:max_box_size =3D> { :val =3D> 40, :type =3D> NumT },
:force_from =3D> { :val =3D> 41, :type =3D> String32T },
:respond =3D> { :val =3D> 42, :type =3D> NumT },
nly_local_domain =3D> { :val =3D> 43, :type =3D> BoolT },
:use_remote_address =3D> { :val =3D> 44, :type =3D> String32T },
:forward_to =3D> { :val =3D> 45, :type =3D> String32T },
:respond_with =3D> { :val =3D> 46, :type =3D> String1024T },
:mail_in =3D> { :val =3D> 47, :type =3D> String32T },
:mail_out =3D> { :val =3D> 48, :type =3D> String32T },
:valid_report =3D> { :val =3D> 49, :type =3D> BoolT },
:delete_older =3D> { :val =3D> 50, :type =3D> BoolT },
:delete_older_days =3D> { :val =3D> 51, :type =3D> NumT },
:forward_older =3D> { :val =3D> 52, :type =3D> BoolT },
:forward_older_days =3D> { :val =3D> 53, :type =3D> NumT },
:forward_older_to =3D> { :val =3D> 54, :type =3D> String32T },
:remote_address =3D> { :val =3D> 55, :type =3D> String32T },
:force_from_address =3D> { :val =3D> 56, :type =3D> BoolT },
:megabyte_send_limit =3D> { :val =3D> 57, :type =3D> NumT },
:number_send_limit =3D> { :val =3D> 58, :type =3D> NumT },
}
def settings_desc; SETTINGS_DESC; end
private :settings_desc
SETTINGS_CALLS =3D {
:get_setting =3D> :GetUserSetting, :set_setting =3D> :SetUserSetting=20
}
def settings_calls; SETTINGS_CALLS; end
private :settings_calls
include Settings

def save
return true unless @buffer
if @index
API.SaveUser(@domain.name, @index, @buffer, @buffer.size)
else
r =3D API.AddUser(@domain.name, @buffer, @buffer.size)
@index =3D r
end
self
end
=20
def delete; API.DeleteUser(@domain.name, @index); end
end # User
=20
def self.init(path)
const_set("API", APIClass.new)
API.Init(path)
end
end


--=-XN87+79wxRM1KhQCmcRq
Content-Disposition: attachment; filename=merak_shell.rb
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

prompt =3D "Merak %3n:%i"
IRB.conf[ROMPT][:Merak_Prompt] =3D {
ROMPT_I =3D> "#{prompt}> ",
ROMPT_C =3D> "#{prompt}* ",
ROMPT_S =3D> "#{prompt}* ",
:RETURN =3D> "=3D> %s\n",
}
IRB.conf[ROMPT_MODE] =3D :Merak_Prompt

require 'merak'
include Merak
Merak.init('C:\Program Files\Merak')

--=-XN87+79wxRM1KhQCmcRq
Content-Disposition: attachment; filename="Merak Shell.bat"
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

@echo OFF=0D
cd \cygwin\home\ADMINI~1=0D
irb -r merak_shell=0D

--=-XN87+79wxRM1KhQCmcRq--


 
Reply With Quote
 
 
 
 
Eivind Eklund
Guest
Posts: n/a
 
      10-28-2004
On Thu, 28 Oct 2004 23:31:05 +0900, Chad Fowler <(E-Mail Removed)> wrote:
> An example of something that I believe is
> broken from an end-user perspective in rpa-base is that when I remove a
> package, it removes all of the dependencies. We _don't_ want to do that
> with RubyGems. I have Rails installed, and I've written scripts to use
> ActiveRecord, which was installed with Rails. If I decide I don't want
> Rails anymore, I don't want to have to go manually install ActiveRecord
> afterward.


Heh. This seems to be a preference issue: I strongly prefer that
dependencies are removed. This is especially important when libraries
are used for application support. I see extra dependencies being left
around as a significant problem when my use is scaled a little bit.

As an example, on one of my FreeBSD systems where I've experiemented
with different software packages and dependencies are not
automatically removed, I presently have 399 software packages
installed. I guess over 100 of these are presently unused
dependencies. These complicate my enviornment, but removing them is
work, and risk breaking things that have added implict dependencies on
them.

In my ideal world (and the design I originally described for RPA), the
dependencies are *hidden* from the user until they are explictly
requested. Thus, your case above cannot happen.

> As for tracking reverse dependencies, it doesn't seem difficult to me:
>
> spec.dependent_gems
>
> The manual user intervention you were talking about is not _necessary_.


I don't get this. Do you mean there is a way to deinstall the
dependencies that the install of a gem auto-installed without manual
intervention? If so, how? I couldn't find it in the documentation -
I'll add it in the places I looked if there is a way.

> We added it because we wanted the user to have the choice to remove a
> package even if it might screw something up.


I don't see how this relate to the above - may we be talking past each other?

> I see it as being in the
> same vein as allowing a programmer to pass a String into a method that may
> usually expect something else. "Here's some rope...you can use it to tie
> knots, secure things, etc. or you can hang yourself with it. We trust
> that you'll make the right decision, because we don't think you're an
> idiot."


I'm an idiot, so I tend to presume that there are others out there, too

I work day-to-day with a package system (FreeBSD's) that do track
reverse dependencies and prevent dropping packages that has a
dependency, but do allow a force switch to override it.

I regularly try to de-install libraries that are in use. Roughly 70%
of those attempted de-installs are by accident, while 30% are ones
that I want to go through with anyway. So I definately appreciate
being caught by the safety-net.

Eivind.
--
Hazzle free packages for Ruby?
RPA is available from http://www.rubyarchive.org/


 
Reply With Quote
 
Mauricio Fernández
Guest
Posts: n/a
 
      10-28-2004
On Thu, Oct 28, 2004 at 11:04:01PM +0900, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> >RubyGems' versioning model makes it difficult to track reverse
> >dependencies: currently user intervention is required to ensure no
> >dependencies are broken on uninstall, and the installation/removal
> >of a RubyGems package plus its dependencies isn't performed as a
> >transaction. There are also some essentially unsolvable issues at runtime
> >(unsatisfiable dependencies).

>
> when a package is installed - do you store dags of the dependancies
> somewhere
> then? i guess it would need to be a single dag (at least logically) so you
> could detect problems on uninstall huh?


It is easy to rebuild the graph on uninstall, based on the stored
dependency information. rpa-base also has a mark and sweep garbage
collector (like Ruby to reclaim unneeded packages. It is very useful
for "build dependencies", but that concept doesn't exist in RubyGems so
they're not in dire need of that.

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com



 
Reply With Quote
 
Chad Fowler
Guest
Posts: n/a
 
      10-28-2004


On Fri, 29 Oct 2004, Bill Guindon wrote:

# On Thu, 28 Oct 2004 23:31:05 +0900, Chad Fowler <(E-Mail Removed)> wrote:
#
# > We trust that you'll make the right decision,
# > because we don't think you're an idiot."
#
# ... unlike Mauricio (and the rest of the RPA team).
#
# That last part didn't add much to the discussion, but it does add to
# the belief that the two teams are antagonistic.
#
# Perhaps I just read it the wrong way.
#

Yea, either that or I wrote it in the wrong way. I was expressing the
philosophy of RubyGems--not implying that the opposite was true of any
other specific developer.

Chad


 
Reply With Quote
 
David Ross
Guest
Posts: n/a
 
      10-30-2004
Curt Hibbs wrote:

>David Ross wrote:
>
>
>>Binary releases are sometimes a problem, most of us are unix users,
>>there are some windows users.
>>
>>

>
>I am a big proponent of being cross-platform *and* making things as easy as
>possible for end users to install and use. So, this is not intended to start
>any kind of competition or flame-war, mostly I'm just curious...
>
>When I see the statement "most of us are unix users, there are some windows
>users" it makes me wonder whether or not this is really true. I'm involved
>in two major cross-platform Ruby projects: FreeRIDE and wxRuby. In both
>cases the windows downloads are higher than all the other platforms
>combined.
>
>It would be interesting if there was a more reliable way to gauge Ruby's use
>on various platforms, but I don't know how that could be done.
>
>Curt
>
>
>
>
>

mmm... Perhaps we can have a long list to a wiki, I'd like to get an
actual headcount. The Ruby Window QA team is all setup. I'm curious if
there are more people who could possibly donate some time or hardware
for the progress of Windows QA support.

David Ross
--
Hazzle free packages for Ruby?
RPA is available from http://www.rubyarchive.org/



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Detailsview shows real numbers with commata: Error converting data type nvarchar to real! Curious Trigger ASP .Net 2 09-09-2006 10:59 PM
OT: The Interview - Real, Funny...Real Funny The Rev [MCT] MCSE 42 05-31-2005 10:42 PM
call any usa REAL telephone number from the internet at pulver freeworld for .06 per minute - have your own real fone # for $10 month!! ucallvoip@yahoo.com VOIP 0 06-09-2004 01:41 AM
product of real and (integer)(after converted to real one) value - vhdl found fatal error senthil VHDL 5 01-24-2004 04:37 AM



Advertisments