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