Initialize an Object with a Block

Initialize an object with a block

Of course, you can yield from within initialize, there's nothing special about it:

class Foo
attr_accessor :bar, :baz
def initialize
yield self
end
end

Foo.new do |f|
f.bar = 123
f.baz = 456
end
#=> <Foo:0x007fed8287b3c0 @bar=123, @baz=456>

You could also evaluate the block in the context of the receiver using instance_eval:

class Foo
attr_accessor :bar, :baz
def initialize(&block)
instance_eval(&block)
end
end

Foo.new do
@bar = 123
@baz = 456
end
#=> #<Foo:0x007fdd0b1ef4c0 @bar=123, @baz=456>

Initialize an object using a block instead of constructor arguments

It's actually really easy to add this functionality to most classes provided they already have attr_writer and/or attr_accessor in place:

class Grammar
attr_accessor :rules, :start, ...

def initialize(rules, start)
@rules = rules
@start = start
...

yield self if block_given?
end
end

Where you can now do exactly what you wanted. The yield self part will supply the object being initialized to the block, and block_given? is only true if you've supplied a block to the new call. You'll want to run this after setting all your defaults.

Initializing an object inside a block

In first case you don't release your dict, and in second case it is autoreleased so you should retain it.

dict = [[NSKeyedUnarchiver unarchiveObjectWithFile:@"dict.dat"] retain];

Ruby: Initialize an Object instance with a block

You could use tap:

Yields self to the block, and then returns self.

Example:

def create_custom_object
Object.new.tap { |o| o.define_singleton_method(:foo) { 'foo' } }
end

object = create_custom_object
#=> #<Object:0x007f9beb857b48>

object.foo
#=> "foo"

How to use an object created inside a try block, outside of it?

Depends on what kind of a default constructor Time has. If its constructor just zeroes three numbers, then your solution is ok.

If its default constructor is expensive (or doesn't exist at all), you can put it into std::optional:

std::optional<Time> t5;
try
{
t5.emplace(23, 59, 59);
}
// ...

A using block, with an object initializer block in the constructor

Object initializers are in some sense a red herring here... but they're one example of where a problem is avoidable.

The object isn't "guarded" by the using statement until the resource acquisition expression has completed normally. In other words, your code is like this:

SomeDisposable tmp = new SomeDisposable();
tmp.MemberThatThrowsAnException = new TypeThatThrowsAnException();

using (SomeDisposable ds = tmp)
{
// Stuff
}

That's more obviously problematic :)

Of course the solution is to assign the property inside the using statement:

using (SomeDisposable ds = new SomeDisposable())
{
MemberThatThrowsAnException = new TypeThatThrowsAnException();
// Stuff
}

Now we're only relying on the constructor of SomeDisposable to clean up after itself if it ends up throwing an exception - and that's a more reasonable requirement.

what is the difference between Initializing a static object inside static block and outside?

In your examples mentioned above both the program is doing the same thing. So you can't judge what is difference between initializing static object and static block. Static block will be called only once at the time of loading the class by the JVM. Purpose of static block is to initialize the static variables and calling static methods. Remember one thing,initialize before you use any resources and for that this is one option which wil be called even before calling the constructor of the class. If you have the requirement to initialize the static variables at the time of loading the class or calling the methods at the time of loading the class to initialize something then in that case static block will be helpful. Here is the example of creating the static object and initializing it in static block.

private static List<String> arrList = new ArrayList<>();
static{
arrList.add("Hello");
arrList.add("World!!!");
}


Related Topics



Leave a reply



Submit