[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Perl Junkie: Bad form?

Chris

8/17/2006 9:20:00 PM

Ok where do I start? :-) A little background...

I've been declaring up and down for 6 years now I'm going to stop using
Perl and start using Ruby. One thing that has always held me back is
not having libraries I've put together in Perl available to me in Ruby.
Instead, I've ported little Ruby tricks over into Perl to the extent
possible. Now I've decided the only way I'm going to use Ruby is start
porting some of the stuff I use in Perl to Ruby.

Here's a little bit of a delimma I have going that I hope to illustrate
using something simple.

I wrote this routine in Perl called "puts" that mostly simulates Ruby's
"puts" statement. (I intend to illustrate something bigger than "puts"
emulation here, so don't let that drag you in. I'm more interested in
the module interaction and EXPORTS [in Perl] and include [in Ruby]
interaction...). Here's the puts() routine in Perl:

sub puts { for (@_) { print "$_\n" } }

That routine is in a Perl module called Utils.pm under a My directory
with puts() EXPORTed. So in a Perl script, I can:

#!/usr/bin/perl
$|++;

use My::Utils;

puts(
"This is line 1",
"This is line 2",
"This is line 3",
);

Now, in Ruby, I find if I construct something similar in a module, I
might create a utils.rb file, place it in the "my" directory under the
Ruby site_ruby directory and have:

module Utils
def Utils.mputs( *args )
args.each { |n| puts n }
end # def
end # module

Then in a Ruby script:

#!/usr/bin/env ruby

require "my/utils"

Utils.mputs(
"This is line 1",
"This is line 2",
"This is line 3"
)

But I don't like having to write "Utils.mputs". In Perl, I exported
the "puts" routine, so in Perl it's in the main namespace and I can
just say: puts( "A", "B", "C" ), etc. I want to be able to do the same
thing in Ruby. Instead of Utils.mputs( blah ), I want to just write
mputs( blah ). So in Ruby, I did this to the Utils module:

module Utils
def mputs( *args )
args.each { |n| puts n }
end # def
end # module

include Utils

Now in my Ruby script, I can do:

#!/usr/bin/env ruby

require "my/utils"

mputs(
"This is line 1",
"This is line 2",
"This is line 3"
)

This is what I would rather be doing, generally, for imported utility
type routines -- making them look "native." I understand (pretty much)
about the separate namespace issue, and namespaces are certainly nice
(both in Perl and in Ruby). But sometimes I want to pretend I have
something "natively" available to me, and this seemed to work.

Ugly? Right? Hackish? A better way? Looking for the Ruby
perspective here because this is probably one of my more unsolved
delimmas -- how to view, approach and implement cases like this.

Thanks!
/usr/ceo

7 Answers

e

8/17/2006 9:32:00 PM

0

/usr/ceo wrote:
> Ok where do I start? :-) A little background...
>
> I've been declaring up and down for 6 years now I'm going to stop using
> Perl and start using Ruby. One thing that has always held me back is
> not having libraries I've put together in Perl available to me in Ruby.
> Instead, I've ported little Ruby tricks over into Perl to the extent
> possible. Now I've decided the only way I'm going to use Ruby is start
> porting some of the stuff I use in Perl to Ruby.
>
> Here's a little bit of a delimma I have going that I hope to illustrate
> using something simple.
>
> I wrote this routine in Perl called "puts" that mostly simulates Ruby's
> "puts" statement. (I intend to illustrate something bigger than "puts"
> emulation here, so don't let that drag you in. I'm more interested in
> the module interaction and EXPORTS [in Perl] and include [in Ruby]
> interaction...). Here's the puts() routine in Perl:
>
> <snip explanation />
>
> This is what I would rather be doing, generally, for imported utility
> type routines -- making them look "native." I understand (pretty much)
> about the separate namespace issue, and namespaces are certainly nice
> (both in Perl and in Ruby). But sometimes I want to pretend I have
> something "natively" available to me, and this seemed to work.
>
> Ugly? Right? Hackish? A better way? Looking for the Ruby
> perspective here because this is probably one of my more unsolved
> delimmas -- how to view, approach and implement cases like this.

The problem is you might be tromping all over the library
user's namespace, possibly overriding methods etc. It is
better to give the 'namespace' and then allow the client
programmer #include the module if they desire shorter access.

Those who remember, I actually advocate allowing the client
programmer create a namespace for libraries instead of the
library writer, too, but that is another discussion.

> Thanks!
> /usr/ceo

--
Posted via http://www.ruby-....

Chris

8/17/2006 10:01:00 PM

0

Eero Saynatkari wrote:
> /usr/ceo wrote:
> > Ok where do I start? :-) A little background...
> >
> > I've been declaring up and down for 6 years now I'm going to stop using
> > Perl and start using Ruby. One thing that has always held me back is
> > not having libraries I've put together in Perl available to me in Ruby.
> > Instead, I've ported little Ruby tricks over into Perl to the extent
> > possible. Now I've decided the only way I'm going to use Ruby is start
> > porting some of the stuff I use in Perl to Ruby.
> >
> > Here's a little bit of a delimma I have going that I hope to illustrate
> > using something simple.
> >
> > I wrote this routine in Perl called "puts" that mostly simulates Ruby's
> > "puts" statement. (I intend to illustrate something bigger than "puts"
> > emulation here, so don't let that drag you in. I'm more interested in
> > the module interaction and EXPORTS [in Perl] and include [in Ruby]
> > interaction...). Here's the puts() routine in Perl:
> >
> > <snip explanation />
> >
> > This is what I would rather be doing, generally, for imported utility
> > type routines -- making them look "native." I understand (pretty much)
> > about the separate namespace issue, and namespaces are certainly nice
> > (both in Perl and in Ruby). But sometimes I want to pretend I have
> > something "natively" available to me, and this seemed to work.
> >
> > Ugly? Right? Hackish? A better way? Looking for the Ruby
> > perspective here because this is probably one of my more unsolved
> > delimmas -- how to view, approach and implement cases like this.
>
> The problem is you might be tromping all over the library
> user's namespace, possibly overriding methods etc. It is
> better to give the 'namespace' and then allow the client
> programmer #include the module if they desire shorter access.
>
> Those who remember, I actually advocate allowing the client
> programmer create a namespace for libraries instead of the
> library writer, too, but that is another discussion.

So are you advocating this (by your last statement especially)?

my/utils.rb:

module Utils
def mputs( *args )
args.each { |n| puts n }
end # def
end # module

myscript.rb:

#!/usr/bin/env ruby

require 'my/utils'
include Utils

mputs(
"Line 1",
"Line 2",
"Line 3"
)

BTW, I am familiar with the fact the one can use "here documents" in
Ruby as well. Again, the simple mputs() routine was intended to
illustrate the require/include interaction -- not to illustrate a way
to write multiple lines (in case someone else comes along and reads it
that way.)

/usr/ceo

David Vallner

8/17/2006 10:25:00 PM

0

On Fri, 18 Aug 2006 00:05:04 +0200, /usr/ceo <newsbot@cox.net> wrote:
>> Those who remember, I actually advocate allowing the client
>> programmer create a namespace for libraries instead of the
>> library writer, too, but that is another discussion.
>
> So are you advocating this (by your last statement especially)?
>
> my/utils.rb:
>
> module Utils
> def mputs( *args )
> args.each { |n| puts n }
> end # def
> end # module
>
> myscript.rb:
>
> #!/usr/bin/env ruby
>
> require 'my/utils'
> include Utils
>
> mputs(
> "Line 1",
> "Line 2",
> "Line 3"
> )

If I understood right, he advocates adding into ruby a construct that
would do:

my/utils.rb:

def mputs( *args )
args.each { |n| puts n }
end

myscript.rb:

require 'my/utils' as Utils
Utils.mputs("Womble", "Fluff")

where if you'd omit the 'as' clause, mputs would be in the global
namespace.

Which is a nifty idea, but I'd also like to see file-scoped or
lexically-scoped require along with it, since this still lets someone
thrash the global namespace for scripts that are unaware of this.

Sander Land

8/17/2006 10:33:00 PM

0

> Ugly? Right? Hackish? A better way? Looking for the Ruby
> perspective here because this is probably one of my more unsolved
> delimmas -- how to view, approach and implement cases like this.
>
> Thanks!
> /usr/ceo

If you're going to put the include statement in the file itself you
might as well add these methods to the Kernel module (where puts is),
but you should be really careful with this if you expect others to use
your code.

Some examples of gems that add methods to Kernel:
Facets can add a lot
(http://facets.rubyforge.org/api/core/classes/K...) , but lets
you include every method separately.
HighLine has everything in modules, but has an extra file that adds
some of these methods to Kernel
(http://highline.rubyforge.org/doc/classes/K...)

phrogz

8/18/2006 4:58:00 AM

0

> This is what I would rather be doing, generally, for imported utility
> type routines -- making them look "native." I understand (pretty much)
> about the separate namespace issue, and namespaces are certainly nice
> (both in Perl and in Ruby). But sometimes I want to pretend I have
> something "natively" available to me, and this seemed to work.
>
> Ugly? Right? Hackish? A better way? Looking for the Ruby
> perspective here because this is probably one of my more unsolved
> delimmas -- how to view, approach and implement cases like this.

You understand the namespace issue, but you know what you want. I'd say
"Go for it!". The power is in your hands. Ruby lets you open up classes
and redefine them after the fact. Why shouldn't you do this at the
global or Kernel level?

(In case it helps, let me plug
http://phrogz.net/RubyLibs/RubyMethodLook... to help you discern
the various areas where you might choose to inject your addons. The
'main' object is an Object.)

One other thing - if you KNOW you always want global functions, why not
just define them as such in the included file?
If you're not sure, then probably you should pull the 'include'
statement out of your separate file. That means when you DO want them
global, you'll need to do:
require 'foo'
include Foo

but at least you'll still have an option.

Logan Capaldo

8/18/2006 5:34:00 AM

0


On Aug 17, 2006, at 6:05 PM, /usr/ceo wrote:

> Eero Saynatkari wrote:
>> /usr/ceo wrote:
>>> Ok where do I start? :-) A little background...
>>>
>>> I've been declaring up and down for 6 years now I'm going to stop
>>> using
>>> Perl and start using Ruby. One thing that has always held me
>>> back is
>>> not having libraries I've put together in Perl available to me in
>>> Ruby.
>>> Instead, I've ported little Ruby tricks over into Perl to the
>>> extent
>>> possible. Now I've decided the only way I'm going to use Ruby is
>>> start
>>> porting some of the stuff I use in Perl to Ruby.
>>>
>>> Here's a little bit of a delimma I have going that I hope to
>>> illustrate
>>> using something simple.
>>>
>>> I wrote this routine in Perl called "puts" that mostly simulates
>>> Ruby's
>>> "puts" statement. (I intend to illustrate something bigger than
>>> "puts"
>>> emulation here, so don't let that drag you in. I'm more
>>> interested in
>>> the module interaction and EXPORTS [in Perl] and include [in Ruby]
>>> interaction...). Here's the puts() routine in Perl:
>>>
>>> <snip explanation />
>>>
>>> This is what I would rather be doing, generally, for imported
>>> utility
>>> type routines -- making them look "native." I understand (pretty
>>> much)
>>> about the separate namespace issue, and namespaces are certainly
>>> nice
>>> (both in Perl and in Ruby). But sometimes I want to pretend I have
>>> something "natively" available to me, and this seemed to work.
>>>
>>> Ugly? Right? Hackish? A better way? Looking for the Ruby
>>> perspective here because this is probably one of my more unsolved
>>> delimmas -- how to view, approach and implement cases like this.
>>
>> The problem is you might be tromping all over the library
>> user's namespace, possibly overriding methods etc. It is
>> better to give the 'namespace' and then allow the client
>> programmer #include the module if they desire shorter access.
>>
>> Those who remember, I actually advocate allowing the client
>> programmer create a namespace for libraries instead of the
>> library writer, too, but that is another discussion.
>
> So are you advocating this (by your last statement especially)?
>
> my/utils.rb:
>
> module Utils
> def mputs( *args )
> args.each { |n| puts n }
> end # def
> end # module
>
> myscript.rb:
>
> #!/usr/bin/env ruby
>
> require 'my/utils'
> include Utils
>
> mputs(
> "Line 1",
> "Line 2",
> "Line 3"
> )
>
> BTW, I am familiar with the fact the one can use "here documents" in
> Ruby as well. Again, the simple mputs() routine was intended to
> illustrate the require/include interaction -- not to illustrate a way
> to write multiple lines (in case someone else comes along and reads it
> that way.)
>
> /usr/ceo
>
>

Yes, this is SOP. The only other thing I would suggest is for modules
like Util (where it's just a collection of "functions" and not
methods) is you do

module Util
def mputs(*args)
args.each { |item| puts item }
end
module_function :mputs
end

This lets you say

Util.mputs

or

include Util
mputs

similar to the Math module.

Jake McArthur

8/20/2006 2:32:00 PM

0

This is your code. You can do whatever you want. It doesn't seem too
far from where many others go here.

That said, why wrap the mputs definition in a module at all if you
are including it into the global namespace immediately after inside
the same file? How about something like this? (mostly untested)

def require_and_include(filename)
require filename
include Kernel.const_get(filename.match(/.*\/?([A-Z][a-z0-9_]*)
(\.rb)?/)[1])
end

require_and_include "my/Utils"

It should work when the name of the file is the same as the name of
the module to include. In this case, you must also make the first
letter of the file name capitalized, but it could be modified easily
to not require that.

- Jake McArthur