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

# 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

···

From: come [mailto:come.news@free.fr]
------------------------------------------------------------------------
     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

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

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

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

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

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

···

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

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

···

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:

Hi --

···

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

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)

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.

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

Regards, Morton

···

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

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