Changing "self" for cleaner code

C

come

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
 
P

Peña, Botp

From: come [mailto:[email protected]]=20
# 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]] ) =3D> obj
obj.instance_eval {| | block } =3D> 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 =3D 99
end
end
k =3D Klass.new
k.instance_eval { @secret } #=3D> 99

=3D> 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
=3D> 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"
=3D> nil
irb(main):023:0>

kind regards -botp
 
G

Gregor Kopp

Peña said:
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
 
C

come

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
 
R

Robert Klemme

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
 
M

Morton Goldberg

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
 
D

David A. Black

Hi --

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


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
G

Gregor Kopp

David said:
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.
 
M

Morton Goldberg

Is that better than just calling the methods without a block? Or if
the variable length is a concern:

o =3D verylongobject

Was just reacting to Gregor Kopp's message without thinking. Boto =20
Pe=F1a's answer is the right one.

Regards, Morton
 
C

come

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top