In Smalltalk, blocks are actual objects in the system like everything else. You can send messages to them (I don't think Ruby allows this). In fact, that's the only way to get something out of a block -- send it the message #value (without args) or #value: (with args) to get some response back.
As the poster above you mentioned, you can then create your own objects that are polymorphic to this pattern if you need to. In other words, make your own object respond to the #value/#value: messages and other objects in the system that are, say, expecting a block can use your custom object all the same.
Objects that are polymorphic with blocks are often called "valuables" precisely because they respond to the #value messages.
> In other words, make your own object respond to the #value/#value: messages and other objects in the system that are, say, expecting a block can use your custom object all the same.
Are there not other messages that they might depend on that would also need to be implemented?
I'm having a hard-time thinking of a case where polymorphic blocks might be useful. Then again, I think Rack middleware (used in Rails for error handling and other things) are somewhat like what you're basically saying, since to define a middleware you mostly just need to define a `call` function. Yet, I'm not sure I'd consider this a block. Maybe the idea would be having the option to use simple blocks as middleware, but having the option to do something more complicated if one wants it.
> Are there not other messages that they might depend on that would also need to be implemented?
The answer to this is "maybe" but it doesn't really matter. You only need to implement the messages that will be sent by other objects and for "valuables" what we care about are the #value/#value: messages for the most part.
We can think of this as some kind of delayed evaluation. Perhaps we define an object who, when sent the #value message, goes off and fetches information from the net or something. We wait until the #value message is sent before doing so, just like we wait to evaluate a block until #value is sent.
An example of methods on Blocks that exist but probably don't need to be implemented for polymorphism are things like #fork and #forkAt which will run the block in it's own separate Process.
> The answer to this is "maybe" but it doesn't really matter. You only need to implement the messages that will be sent by other objects and for "valuables" what we care about are the #value/#value: messages for the most part.
If one is trying to pass a block-like object to a message that is expecting a block and which we cannot be easily sure is not dependent on other messages under obscure conditions, is it not easier to extend from / inherit whatever class the blocks in Smalltalk use (i.e. the equivalent of Proc in Ruby)? Or is it that documentation of such methods explicitly mention that they support not just Smalltalk blocks but also other "valuables"?
> An example of methods on Blocks that exist but probably don't need to be implemented for polymorphism are things like #fork and #forkAt which will run the block in it's own separate Process.
I mean, sure, you can intuitively guess that such messages might not be needed, but it might not always be such an easy thing to guess. Ruby Procs have the methods `arity` and `parameters` for example, which could be widely used to inspect the parameters accepted by a block to decide how to pass arguments in. I never used such methods, but it might be that methods from other libraries to which I pass these blocks could use them. I don't know.
I guess it could be a language culture thing. Dependence on only `#value` / `#value:` could be common convention in Smalltalk if usage of valuables is a more common idiom.
> If one is trying to pass a block-like object to a message that is expecting a block and which we cannot be easily sure is not dependent on other messages under obscure conditions, is it not easier to extend from / inherit whatever class the blocks in Smalltalk use (i.e. the equivalent of Proc in Ruby)?
For Smalltalkers this is just the difference between inheritance vs composition. Sometimes you don't want to directly inherit because your object's implementation of something like #value: is going to be quite different (ie, "mean" something different to the implementor -- but not necessarily the sender). By using composition over inheritance you avoid having to call the super's version, which would be something like:
value: aParameter
self doSomeInternalProcessingWith: aParameter.
super value: aParameter.
> Or is it that documentation of such methods explicitly mention that they support not just Smalltalk blocks but also other "valuables"?
Yeah so you will see methods that look kind of like this:
Here the variable name in the definition hints to the reader what it should be like (this is common in Smalltalk).
The "valuable" pattern-ish thing is not used super often as far as I've seen. Pharo uses it in composing Announcements and I think UI packages like the make use of it too.
First-class functions/closures are essentially polymorphic blocks. This is because, in the general case, a call through a first-class function might be followed by a dispatch step in which different blocks of code can be "selected" to run depending on runtime data.
To build on this, related to the theme of blocks: Smalltalk syntax is almost entirely free of magical constructs that you can't easily replicate in user code (off the top of my head `self`, `super`, the `[]` syntax for blocks, and compile-time literals can't be replicated), literally everything in Smalltalk is messages to objects (or method calls on objects in contemporary OO terms); thus a conditional which would be `if() { ... } else { ... }` in an Algol language is done by passing the `ifTrue:ifFalse:` message to a boolean object. Thus, if you need a custom control structure, you can implement them yourself and it'll be just like any other control structure in the language.