[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Changing "self" for cleaner code

come

8/23/2007 7:26:00 AM

Hi,

Is it possible to change the value of self just to enter the context
of an object, like for example in IRB ? For instance, is it possible
to write something like :

File.open("file.txt","w") do
puts "Hello World"
end

With irb, you could do something like :

irb(main):001:0> f=File.open("_vimrc","r")
=> #<File:_vimrc>
irb(main):002:0> irb f
irb#1(#<File:0x2e3784c>):001:0> a=readlines
=> ["set guifont=Bitstream_Vera_Sans_Mono:h9:cANSI \n", ...

I ask that because I'm doing a program to access different unix os and
I would like to write something like :

with my_server do
ls("-lrt")
ps("-efl")
end

instead of

my_server.new do |host|
host.ls("-lrt")
host.ps("-efl")
end

Just for cleaner code...

Come

9 Answers

Peña, Botp

8/23/2007 7:45:00 AM

0

From: come [mailto:come.news@free.fr]
# I ask that because I'm doing a program to access different unix os and
# I would like to write something like :
# with my_server do
# ls("-lrt")
# ps("-efl")
# end

is instance_eval ok for you?

irb(main):013:0> system "qri instance_eval"
--------------------------------------------------- Object#instance_eval
obj.instance_eval(string [, filename [, lineno]] ) => obj
obj.instance_eval {| | block } => obj
------------------------------------------------------------------------
Evaluates a string containing Ruby source code, or the given
block, within the context of the receiver (obj). In order to set
the context, the variable self is set to obj while the code is
executing, giving the code access to obj's instance variables. In
the version of instance_eval that takes a String, the optional
second and third parameters supply a filename and starting line
number that are used when reporting compilation errors.

class Klass
def initialize
@secret = 99
end
end
k = Klass.new
k.instance_eval { @secret } #=> 99

=> true

some simple example,

irb(main):014:0> def with x, &block
irb(main):015:1> x.instance_eval &block
irb(main):016:1> end
=> nil
irb(main):017:0> with "test" do
irb(main):018:1* p length
irb(main):019:1> p upcase
irb(main):020:1> p capitalize
irb(main):021:1> p self
irb(main):022:1> end
4
"TEST"
"Test"
"test"
=> nil
irb(main):023:0>

kind regards -botp

Gregor Kopp

8/23/2007 8:23:00 AM

0

Peña wrote:
> some simple example,
>
> irb(main):014:0> def with x, &block
> irb(main):015:1> x.instance_eval &block
> irb(main):016:1> end
> => nil
> irb(main):017:0> with "test" do
> irb(main):018:1* p length
> irb(main):019:1> p upcase
> irb(main):020:1> p capitalize
> irb(main):021:1> p self
> irb(main):022:1> end
> 4
> "TEST"
> "Test"
> "test"
> => nil
> irb(main):023:0>
>
> kind regards -botp
>

Another way:

class Object
def with &block
yield self
end
end

verylongobject = "Hakuna Matata!"

verylongobject.with do |o|
puts o #-> Kakuna Matata!
puts o.length #-> 14
puts o.reverse #-> !atataM anukaH
puts o.upcase #-> HAKUNA MATATA!
end

come

8/23/2007 10:25:00 AM

0

Yes !
I didn't think about using instance_eval this way and define my own
"with" method... I'm still not confortable with metaprogramming ;-)

Thank you both,
Come

On 23 ao?t, 10:23, Gregor Kopp <g...@cutcopy.com> wrote:
> Pe?a wrote:
> > some simple example,
>
> > irb(main):014:0> def with x, &block
> > irb(main):015:1> x.instance_eval &block
> > irb(main):016:1> end
> > => nil
> > irb(main):017:0> with "test" do
> > irb(main):018:1* p length
> > irb(main):019:1> p upcase
> > irb(main):020:1> p capitalize
> > irb(main):021:1> p self
> > irb(main):022:1> end
> > 4
> > "TEST"
> > "Test"
> > "test"
> > => nil
> > irb(main):023:0>
>
> > kind regards -botp
>
> Another way:
>
> class Object
> def with &block
> yield self
> end
> end
>
> verylongobject = "Hakuna Matata!"
>
> verylongobject.with do |o|
> puts o #-> Kakuna Matata!
> puts o.length #-> 14
> puts o.reverse #-> !atataM anukaH
> puts o.upcase #-> HAKUNA MATATA!
> end


Robert Klemme

8/23/2007 7:34:00 PM

0

On 23.08.2007 12:24, come wrote:
> Yes !
> I didn't think about using instance_eval this way and define my own
> "with" method... I'm still not confortable with metaprogramming ;-)

You don't need to. You can simply use instance_eval directly:

File.open("foo", "w") do |x|
x.instance_eval do
puts "hello"
end
end

Although I have to say I find this a bit clumsy. I'd prefer

File.open("foo", "w") do |io|
io.puts "hello"
end

Even if there were more IO operations I had to do on "io". The piece
above could be easily confused with printing to $defout. Just my 0.02EUR...

Kind regards

robert

Morton Goldberg

8/23/2007 11:39:00 PM

0

On Aug 23, 2007, at 5:45 AM, Gregor Kopp wrote:

> Another way:
>
> class Object
> def with &block
> yield self
> end
> end
>
> verylongobject = "Hakuna Matata!"
>
> verylongobject.with do |o|
> puts o #-> Kakuna Matata!
> puts o.length #-> 14
> puts o.reverse #-> !atataM anukaH
> puts o.upcase #-> HAKUNA MATATA!
> end

With a small modification the OP can get exactly the syntactic form
he wants:

<code>
def with obj
yield obj
end

verylongobject = "Hakuna Matata!"

with verylongobject do |o|
o # => "Hakuna Matata!"
o.length # => 14
o.reverse # => "!atataM anukaH"
o.upcase # => "HAKUNA MATATA!"
end
</code>

Regards, Morton

David A. Black

8/24/2007 1:07:00 AM

0

Gregor Kopp

8/24/2007 7:23:00 AM

0

David A. Black wrote:
> Is that better than just calling the methods without a block? Or if
> the variable length is a concern:
>
> o = verylongobject
>
>
> David

Your'e right!

<code>
class Object
def with &block
yield self
end
end

class Testclass < String
end

verylongobject = Testclass.new("Hakuna Matata!")

puts verylongobject.object_id

verylongobject.with do |o|
puts o.object_id
end

o = verylongobject
puts o.object_id
</code>

It gives all the same object_id, so no copies should fly around, so
giving it another name should be the best.

Morton Goldberg

8/24/2007 7:33:00 AM

0

On Aug 23, 2007, at 9:06 PM, David A. Black wrote:

> On Fri, 24 Aug 2007, Morton Goldberg wrote:
>
>> On Aug 23, 2007, at 5:45 AM, Gregor Kopp wrote:
>>
>>> Another way:
>>> class Object
>>> def with &block
>>> yield self
>>> end
>>> end
>>> verylongobject = "Hakuna Matata!"
>>> verylongobject.with do |o|
>>> puts o #-> Kakuna Matata!
>>> puts o.length #-> 14
>>> puts o.reverse #-> !atataM anukaH
>>> puts o.upcase #-> HAKUNA MATATA!
>>> end
>>
>> With a small modification the OP can get exactly the syntactic
>> form he wants:
>>
>> <code>
>> def with obj
>> yield obj
>> end
>>
>> verylongobject = "Hakuna Matata!"
>>
>> with verylongobject do |o|
>> o # => "Hakuna Matata!"
>> o.length # => 14
>> o.reverse # => "!atataM anukaH"
>> o.upcase # => "HAKUNA MATATA!"
>> end
>> </code>
>
> Is that better than just calling the methods without a block? Or if
> the variable length is a concern:
>
> o = verylongobject

Was just reacting to Gregor Kopp's message without thinking. Boto
Peña's answer is the right one.

Regards, Morton



come

8/24/2007 10:44:00 PM

0

Thanks for your anwser.
I knew I could write the form "File.open(...) do |x| ... end". I read
nearly all books on Ruby/Rails right now ;-). The last I'm reading is
"Practical Ruby for System Administration", Apress. A good book, too.
I was surprised.
But I cant't practice as often as I would, so I miss some automatism.

I was asking myself if i couldn't write something like :

with my_object do something end

instead of :

with my_object do |o| o.something end

I found it would be a little bit cleaner to write like that. The first
answer gave me an answer : I can define "with" myself.

Come

On 23 aug, 21:34, Robert Klemme <shortcut...@googlemail.com> wrote:
> On 23.08.2007 12:24, come wrote:
>
> > Yes !
> > I didn't think about using instance_eval this way and define my own
> > "with" method... I'm still not confortable with metaprogramming ;-)
>
> You don't need to. You can simply use instance_eval directly:
>
> File.open("foo", "w") do |x|
> x.instance_eval do
> puts "hello"
> end
> end
>
> Although I have to say I find this a bit clumsy. I'd prefer
>
> File.open("foo", "w") do |io|
> io.puts "hello"
> end
>
> Even if there were more IO operations I had to do on "io". The piece
> above could be easily confused with printing to $defout. Just my 0.02EUR...
>
> Kind regards
>
> robert