0

So I am trying to write the method_missing in Ruby, the method_missing has three parameter as shown

def method_missing(mId,*args,&block)
     if (args.empty? && !block_given?)
          puts " Sample One  No arguments were given nor block"
      elsif (!args.entries.empty?)
          puts " there was arguments given"
      elsif (block_given?)
           puts "there was ?code given"
    end 
end 

The problem calling instance.anything { " block" } always returns " Sample One No arguments were given nor block". it's clear that block_given always returns false , but why?

2 Answers2

2

You have a bit overcomplicated logic in your method and that's the main reason why it doesn't work according to your expectations. There is no issue with block_given?

Also, I don't see any reason in args.entries.empty? usage. args.empty? gives you the same result, but it looks more clear.

Original method could be rewritten like this, but I would notice that you didn't cover a case when the method can be called with arguments and a block. I don't know if it was an intent or not.

def method_missing(mid, *args, &block)
  if args.count > 0
    puts "there were arguments found"
  else
    if block_given?
      puts "there was a code found"
    else
      puts "Sample One  No arguments were given nor block"
    end
  end
end   

Example which shows that block_given? works properly:

class A
  def method_missing(mid, *args, &block)
    p block
    p block_given?
  end
end

A.new.aaaa
nil
false
 => false 

A.new.aaaa { "aaaa" }
#<Proc:0x007fabd313d090@(irb):8>
true
 => true  
SunnyMagadan
  • 1,819
  • 14
  • 12
  • I wan't to certain procedure to happens when there is an empty 1-empty argument, 2-key-value pair have been passed in the argument, 3-block of code have been passed. Consider that the when passing the block of code there would be arguments given which also satisfy case 1. – Ghassan Maslamani Aug 01 '16 at 20:45
  • If you want to check if keyword arguments were passed in the method then use double splat notation for collecting them into a variable and then refer to this variable of a Hash type. method_missing(mid, *args, **kwargs, &block) https://flushentitypacket.github.io/ruby/2015/03/31/ruby-keyword-arguments-the-double-splat-and-starsnake.html http://stackoverflow.com/questions/18289152/what-does-a-double-splat-operator-do – SunnyMagadan Aug 02 '16 at 07:03
0

This one took a bit of puzzling.

There is nothing wrong with block_given, except your check is nested in an "if else" block. (That's the Too Long; Didn't Read summary)

You would only see "there was code given" if you passed in no arguments into your function. Passing in arguments triggers the !args.entries.empty? if, the if gets matched and any further else statements are not executed.

(Try this at home: try to call your method with no arguments and just a block, then with arguments and a block).

If your expected / desired output is: there was arguments given there was ?code given

Then try this method instead. Note how I made your last elsif a plain if statement:

def method_missing(mId,*args,&block) if (args.empty? && !block_given?) puts " Sample One No arguments were given nor block" elsif (!args.entries.empty?) puts " there was arguments given" end if (block_given?) puts "there was ?code given" end
end

RyanWilcox
  • 13,890
  • 1
  • 36
  • 60
  • In the last line of the question, the OP writes that calling `instance.anything { " block" }`, i.e. with no arguments but with a block also doesn't work, which does not match up with your explanation. – Jörg W Mittag Aug 01 '16 at 18:57
  • Didn't worked it executes also puts " Sample One No arguments were given nor block" – Ghassan Maslamani Aug 01 '16 at 20:47