1

I have a class Notification::Pseudo in my rails application that has a custom initialize method. I would like this method to capture the output of the block that was passed to new and use that as the value for @message

class Notification::Pseudo
  attr_accessor :message
  def initialize(&block)
    @message = begin
      capture(&block) if block_given?
    end || ""
  end
end

In my view I then have something like

- notification = Notification::Pseudo.new do
  This is a test!

This doesn't work though. This gives me the error ArgumentError: wrong number of arguments (0 for 1).

What is wrong w/ my initializer?

6
  • Where is the capture method coming from? The error lies there I think. Commented Jan 28, 2014 at 16:01
  • api.rubyonrails.org/classes/ActionView/Helpers/… Commented Jan 28, 2014 at 16:01
  • This is a method available in views and templates but you're using it on a class. What exactly do you want your @message to be in the case of your example? Commented Jan 28, 2014 at 16:03
  • @message should become what ever is yielded from the block (in my example it would be "This is a test!"). Commented Jan 28, 2014 at 16:03
  • Show us exactly your view. "This is a test" is a string? Commented Jan 28, 2014 at 16:05

1 Answer 1

2

capture method you are calling is defined on Kernel module. You want to call capture from ActionView::Helpers::CaptureHelper module. It is automaticaly included into view context and you need to run it in this context so you need:

class Notification::Pseudo
  attr_accessor :message
  def initialize(vc, &block)
    @message = begin
      vc.capture(&block) if block_given?
    end || ""
  end
end

#In your view

- notification = Notification::Pseudo.new self do
  This is a test!

UPDATE:

To make it work also outside of the view, do:

class Notification::Pseudo
  attr_accessor :message
  def initialize(vc = nil, &block)
    @message = begin
      return unless block_given?
      vc ? vc.capture(&block) : block.call
    end || ""
  end
end
Sign up to request clarification or add additional context in comments.

4 Comments

This would work if always initializing a Notification::Pseudo object from somewhere that had a view context but what about if I attempted to create on from the console? What is the proper way to do this without using a view context?
@KyleDecot Well, that depends on what you want it to do in that context. Let vc = nil by default, and then add logic to your constructor to make it behave differently if vc == nil.
Capture is to be used within a template - otherwise it has absolutely no sense to use it (It is internally calling Erb utils etc). You can fork it on existence of vc variable so this method is not called without view context.
That makes sense when you explain it like that. I didn't think about the view context being such an important part of the process. Thanks for breaking it down like that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.