Changing "self" for cleaner code

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

Peña wrote:

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

From: come [mailto:[email protected]]

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

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

Just for cleaner code…

Come

Check out Puppet (http://reductivelabs.com/trac/puppet), which is
entirely
written in Ruby and will do that (and much more) for you.

Yes !
I didn’t think about using instance_eval this way and define my own
“with” method… I’m still not confortable with metaprogramming :wink:

Thank you both,
Come

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 :wink:

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

Hi –

On Fri, 24 Aug 2007, Morton G. wrote:

verylongobject = “Hakuna Matata!”

o.upcase # => “HAKUNA MATATA!”
end

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

o = verylongobject

David

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

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:

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

Regards, Morton

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!

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

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

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 Aug 23, 2007, at 9:06 PM, David A. Black wrote:

verylongobject = “Hakuna Matata!”

o.upcase # => “HAKUNA MATATA!”
end

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 K.'s message without thinking. Boto
Peña’s answer is the right one.

Regards, Morton